The Joint Strike Fighter Coding Standard - Bill Emshoff - CppCon 2014.pptx


Loading.... (view fulltext now)





Full text



Bilill l EEmmsshohoff ff 


 Senienior Sor Stataff Eff Embedded mbedded SS//W EW Engngiineer neer 


Lockockheeheed Mad Martin Artin Aeronaeronaututicicss



Using C++ on Mission

Using C++ on Mission

and Safety Critical

and Safety Critical



Background and Philosophy behind the

Background and Philosophy behind the JSF++




Coding Issues Distinct to JSF++

Coding Issues Distinct to JSF++

(vs. those for General-Purpose Software)

(vs. those for General-Purpose Software)

Automated JSF++ compliance testing

Automated JSF++ compliance testing

Lessons Learned

Lessons Learned



Background and Philosophy behind the

Background and Philosophy behind the JSF++




Coding Issues Distinct to JSF++

Coding Issues Distinct to JSF++

(vs. those for General-Purpose Software)

(vs. those for General-Purpose Software)

Automated JSF++ compliance testing

Automated JSF++ compliance testing

Lessons Learned

Lessons Learned



In the late 1990’s, Lockheed Martin selected

In the late 1990’s, Lockheed Martin selected C++


as the programming language to be used

as the programming language to be used for Joint

for Joint

Strike Fighter embedded softw

Strike Fighter embedded software development

are development




 A da

da tool

tool cchai


ns wer


e iin decli

n decline







+ ttool


s we

werre imp

e imprrovi








+ wa


s a


accttiive t

ve to p

o prros

os pe

peccttiive e

ve eng

ng iinee


History (1/2)


In the Fall of 2003, Bjarne Stroustrup provided

assistance to JSF engineers in the development of

coding guidelines – “JSF++”


 Many s ources of C and C++ prog ramming

 g uidelines were available, but no s ing le s et of

 g uidelines were found suitable for the

cons traints of our environment 


• MISRA C 1998


Us ed as the bas is for J S F++, but:


Limited to C lang uag e cons tructs


C++ obviates the need for many C -s pecific rules

 – Stronger type-checking

 – Templates can replace macros

 – Container classes are safer alternatives to C


 – Smart Pointers are safer alternatives to C


• Embedded C++


Overly limited subs et of C++ omitting features deemed

ess ential to larg e projects

• No namespaces, templates, or multiple inheritance


• Hard Real Time

 – Failure to meet schedule can be a fatal error 

• Limited Memory

 – Memory is fixed to that physically available - no memory


• Safety and/or Mission Critical Applications  – Failure can cause loss of life or aircraft • Portability

 – Code must run on multiple operating systems to support

development and simulation

• Maintainability

 – Code will likely need to be maintained for



C makes it eas y to shoot yours elf in the foot; C ++ makes it

harder, but when you do it blows your whole leg off.

― Bjarne Stroustrup

• Define a common style for all developers that is easy to

comprehend and maintain

• Avoid undefined, unspecified, and implementation-defined



Code s hould have predictable and portable s emantics

and performance

• Provide safe alternatives to unsafe or error-prone features  –

Often in the form of library components

• Automatic verification of guidelines is an important goal  –

Promote s tatic over dynamic error detection whenever

 pos s ible


• Resource Management in JSF++ • Arrays

• Multiple Inheritance

• Fault Handling



• Life without RTTI (Run-time type information)

• Templates

• Summary Comparison of JSF++ and MISRA C++ 2008

Coding Standard topics relevant to



• Allocation from the free store (global new/delete) is

prohibited except during initialization (JSF Rule 206)


Fragmentation of the heap due to repeated

allocation/de-allocation leads to non-determinis tic performance

• The JSF container library provides STL-style, class-specific

allocators as alternatives to eliminate the possibility of fragmentation

 – C++ STL vector’s interface allows class-specific

allocators as an


; for JSF’s container library, they are essentially


 – By defining fixed-size memory pools at initialization time,

constant-time new/delete can be guaranteed

 – No need to pay overhead costs for thread-safe allocators

for objects only accessed in a single thread


• Replacing global new/delete with custom allocators resolves

some performance issues but doesn’t guarantee safe operation

• C pointers and raw resource handles can lead to a host of

potential problems:

T* p = new T;

if (p->fail1) return 0; // leak!

if (p->fail2) delete p; // p is now a dangling pointer! return p; // does caller know he now “owns” p?

R eturn values s hould not obs cure res ource owners hip


RAII to the Rescue

• The Resource Acquisition Is Initialization (RAII) idiom solves

many pointer problems:

shared_ptr<T> p ( new T);

if (p->fail1) return 0; // No leak!

if (p->fail2) delete p; // Does not even compile! return p; // caller gets ownership,


With self-managed (RAII) class attributes, the

implementer is relieved of a lot of work in

class implementation

The compiler-generated copy constructor,

assignment operator, and destructor should

 just “do the right thing”, so there is no need

for the developer to write one (JSF rule 80)

RAII is not limited to pointers – mutexes are

likewise wrapped in RAII classes (e.g. C++11



• The use of arrays in interfaces is prohibited in JSF++


The problems of pointer decay have a long , notorious


 foo( int*p ) // a function taking a pointer to an integer   foo( int[2] )  // really no different…

• JSF’s container library provides Array-like container classes

that avoid these problems

F oo( A rray<int,2>& )

// much s afer  

 – Containers know their own size and don’t participate in

implicit pointer convers ions

For the s pecial cas e of dealing with external / leg acy

interfaces implemented with arrays , template wrapper

 functions can help:

template <clas s T, s ize_t N> void foo(T (&p)[N]) …


• MI is allowed in a restricted form to allow for clean,

maintainable designs (JSF rule 88):

 – Unlimited public



 – Unlimited private



 – Plus at most 1 protected, inherited implementation

 – MI is specifically allowed for “policy-based design” [1],

with each base class representing independent facets of the derived class

• For the purposes of this JSF++ rule, an



contain :

 – non-virtual, protected methods

 – small data items if they function as part of the interface


 Modern C++ Des ig n

, by Andrei Alexandrescu


• Exceptions are prohibited in JSF++


 A t the time J S F++ was defined, various C++ compiler

implementations res ulted in widely varying overheads


B etter tool s upport was deemed neces s ary prior to

allowing C ++ exceptions in critical code

• Will all exceptions be caught?

• Is all affected code exception-safe?

• Are all possible control-paths covered?

• Disabling C++ exceptions doesn't eliminate the need for

fault handling though…

Fault Handling





• In general, functions should return error information, and

calling functions must test it (JSF rule 115)


Problem for automated verification:

how is

“error information”

defined and returned? 

 S implis tic tool ass umption:

if a function returns a value, it must be used or cast to void

Fault Handling





• What about constructors, overloaded operators, or other

functions that don't return a status value?

 – Consider moving potentially-failing constructor code to

separate initialization / factory methods

 – Use a class attribute as a status indication, e.g.,

Matrix m = a + b; //

what to do if a + b fails ? 

if (m.is_bad()) { /* handle error case */ }

Compilers and lint-tools handily complain about

unused return values, but relying on users to check

error codes set as side-effects is inherently error-prone (a reason why JSF++ disparages use of errno).

 – Some errors are patently unrecoverable

For never-should-happen errors (failed assertions, watchdog timeouts, hardware failures) – log the fault data and try a reboot

Fault Handling





• For somewhat similar reasons that JSF++ banned C++ exceptions,

RTTI is also banned (JSF rule 178)

 – Worst-case overhead not easily predictable

• Often, a perceived need for RTTI is an indication of design

problems better solved with abstract methods

• In lieu of dynamic_cast, the Visitor Pattern can be used – this

requires no typecasts at all; users can derive from a class such as this:

class DefaultVisitor : Visitor { virtual defaultImpl(Base&) {}

virtual visit(Derived1& d) { defaultImpl(d); } virtual visit(Derived2& d) { defaultImpl(d); } ...


Life without RTTI


• JSF++ allows templates as a means to achieve type-safe,

high-performance code; however, C++ template usage

introduces additional challenges for development, analysis, and testing

 – Template code cannot be completely analyzed until


 – Each unique template instantiation requires its own test

and review if in critical code


• MISRA C++ builds on JSF++ as JSF++ built on MISRA C • With an additional ~five years of compiler and developer

community maturity, MISRA 2008 allows, with restrictions,

 – C++ exceptions

 – dynamic_cast (RTTI)

• In keeping with original MISRA C rules, MISRA 2008



use of the free store (heap), even for initialization

• JSF++ forbids use of NULL macro due to C++ type checking;



it (as being more expressive than “0”)

 – Should consider C++11’s nullptr for future coding


• JSF++ includes style guidelines; MISRA C++ recognizes

style is subjective, and given its more general target

audience, only suggests that an in-house style guide should exist

Summary Comparison of JSF++ and

MISRA C++ 2008


• Commercial static analysis tools providing automated

compliance checking are available from multiple vendors

 – Rules that are checked automatically are rules that

developers don’t need to waste review time on, and can instead concentrate on the tough problems

 – Automatic rule checkers catch issues commonly missed

by human eyes, sometimes even testing, e.g.,

• use of “=” vs. “==”

• inadvertent semi-colon following a conditional


• ensuring all attributes of a class are initialized in a



 – Static analysis is essential (and relatively cheap) but no

substitute for code review

 – Issues of style or that require human interpretation are

especially problematic for automated checks, e.g.,

• JSF rule 45 - words in an ID will be separated by ‘_’.

 – How should a tool determine what is a “word” 

• JSF rule 88 – multiple public interface inheritance

 – R ule text includes intent in the definition of interface.

• JSF rule 113 - multiple return statements are banned

unless s uch a s tructure would obscure or otherwis e

 s ig nificantly


 – How s hould a tool implement this rule? 


 – Automated rules produce tradeoffs

• Tools erring towards catching more true positives at

the expense of more false positives result in

increased developer time to review and filter results and possibly “fix” or annotate code to meet tool


• Tools erring towards generating fewer false positives

tend to do so at the expense of missing some true positives

Often, code that triggers a “false” positive is code that

may be too clever and could stand a bit of critical

review anyway 


• A consistent, easy-to-read coding style for naming, braces, and

indention is more important than the particular style itself 

 – Developers modifying legacy code modules should be

encouraged to follow the existing style in those modules rather than resort to either leaving a module in JSF++ / K&R mixed style or refactoring existing working code

• Even in the absence of exceptions, the “resource acquisition is

initialization” (RAII) idiom generally, and smart pointers

specifically, should be explicitly required for resource handling

• Rules with subtle or exceptional cases can be difficult to analyze


• JSF++ includes guidelines on good template design, but failed to

specifically identify portability issues related to templates, notably

 – Some compilers didn't require typename at all; some allowed it

in contexts prohibited by others (and by the C++ standard)

 – Dependent base class name lookup implementations varied



• A rationale for each rule educates developers and gets their buy-in  – Compliance comes easier when developers understand


• Interpretation of rules would be enhanced by more pass/fail


 – not just novices, but even experienced implementers of

rule-checker software have sometimes missed the full intent of rules

• Rules should be written with automated compliance in mind,

leaving little to ambiguity

Consider rule 142, “All variables shall be initialized before use”. This could be enforced for local variables by requiring

initialization at declaration, but the standard is largely silent on how this rule is to be verified. By comparison, the related MISRA rule 8-5-1 specifically does not require initialization at

declaration, but does require class constructors to initialize all non-static members.


• Don’t over-specify

 – rather than prescribe use of a particular “Array” class in lieu of

an array, simply specify that library container classes be used

• Provide more clear guidance on how to deal with non-compliant

automatically-generated code, such as from UML tools

 – Where possible, common tool configuration settings should be

supplied to teams to achieve consistent code generation, as consistent with the coding standard as practical


• With a more mature C++ developer community, and better tool

support, C++ exception handling should be considered for future safety-critical applications

 –  A llows error handling log ic to be cons olidated at a hig her level

than deeply-nested functions

 – E liminates need for code to explicitly check and pas s error

 s tatus for truly exceptional events

• The coding standards will need to be revised for future

applications using C++11 (C++14?), which in many ways “feels like a new language” to quote Bjarne Stroustrup


 – After 15 years and more than 8 million lines of software

code [1], JSF++ has been a decided success for the JSF program

C ++ is now in widespread us e throug hout indus try

with excellent tool chains broadly available

Lig ht-weig ht, express ive abstraction mechanis ms

 provide J S F eng ineers with crucial s upport for

manag ing complexity without incurring performance


When aug mented with reas onable g uidelines and

 s uitable libraries , C++ has proven its elf for s

afety-critical application

100+ F-

35’s in the field today 

• [1]






Related subjects :