Saturday, September 12, 2015

Summary of JSF Air Vehicle C++ Coding Standards




JOINT STRIKE FIGHTER
AIR VEHICLE
C++ CODING STANDARDS
FOR THE SYSTEM DEVELOPMENT AND DEMONSTRATION PROGRAM Document Number 2RDU00001 Rev C 
December 2005 
Copyright 2005 by Lockheed Martin Corporation.
DISTRIBUTION STATEMENT A: Approved for public release; distribution is unlimited. 

1 INTRODUCTION
The intent of this document is to provide direction and guidance to C++ programmers that will enable them to employ good programming style and proven programming practices leading to safe, reliable, testable, and maintainable code... As indicated above, portions of Air Vehicle (AV) code will be developed in C++... Overall, the philosophy embodied by the rule set is essentially an extension of C++’s philosophy with respect to C. That is, by providing “safer” alternatives to “unsafe” facilities, known problems with low-level features are avoided.

2 REFERENCED DOCUMENTS

3 GENERAL DESIGN

3.1 Coupling & Cohesion 
Coupling and cohesion are properties of a system that has been decomposed into modules. Cohesion is a measure of how well the parts in the same module fit together. Coupling is a measure of the amount of interaction between the different modules in a system. Thus, cohesion deals with the elements within a module (how well-suited elements are to be part of the same module) while coupling deals with the relationships among modules (how tightly modules are glued together). 
Object-oriented design and implementation generally support desirable coupling and cohesion characteristics. The design principles behind OO techniques lead to data cohesion within modules. Clean interfaces between modules enable the modules to be loosely coupled. Moreover, data encapsulation and data protection mechanisms provide a means to help enforce the coupling and cohesion goals. 
Source code should be developed as a set of modules as loosely coupled as is reasonably feasible. Note that generic programming (which requires the use of templates) allows source code to be written with loose coupling and without runtime overhead. 
Examples of tightly coupled software would include the following:
• many functions tied closely to hardware or other external software sources, and
• many functions accessing global data.
There may be times where tightly coupled software is unavoidable, but its use should be both minimized and localized as suggested by the following guidelines:
• limit hardware and external software interfaces to a small number of functions,
• minimize the use of global data, and
• minimize the exposure of implementation details. 

3.2 Code Size and Complexity 

AV Rule 1
Any one function (or method) will contain no more than 200 logical source lines of code (L- SLOCs).
Rationale: Long functions tend to be complex and therefore difficult to comprehend and test. 

AV Rule 3
All functions shall have a
cyclomatic complexity number of 20 or less.
Rationale: Limit function complexity. 

4 C++ CODING STANDARDS 

4.6 Pre-Processing Directives 

AV Rule 28
The #ifndef and #endif pre-processor directives will only be used as defined in AV Rule 27 to prevent multiple inclusions of the same header file.
Rationale: Conditional code compilation should be kept to a minimum as it can significantly obscure testing and maintenance efforts. 

4.9 Style 

AV Rule 41
Source lines will be kept to a length of 120 characters or less.

Rationale: Readability and style. Very long source lines can be difficult to read and understand. 

AV Rule 49
All acronyms in an identifier will be composed of uppercase letters.
Note: An acronym will always be in upper case, even if the acronym is located in a portion of an identifier that is specified to be lower case by other rules.
Rationale: Readability. 

4.9.4 Functions 

AV Rule 58
When declaring and defining functions with more than two parameters, the leading parenthesis and the first argument will be written on the same line as the function name. Each additional argument will be written on a separate line (with the closing parenthesis directly after the last argument).
Rationale: Readability and style. 

4.9.5 Blocks 

AV Rule 59 (MISRA Rule 59, Revised)
The statements forming the body of an if, else if, else, while, do...while or for statement shall always be enclosed in braces, even if the braces form an empty block.
Rationale: Readability. It can be difficult to see “;” when it appears by itself. 

4.9.6 Pointers and References

AV Rule 62
The dereference operator ‘*’ and the address-of operator ‘&’ will be directly connected with the type-specifier.
Rationale: The int32* p;form emphasizes type over syntax while the int32 *p; form emphasizes syntax over type. Although both forms are equally valid C++, the heavy emphasis on types in C++ suggests that int32* p; is the preferable form. 

4.10 Classes
4.10.3 Member Functions 

AV Rule 68
Unneeded implicitly generated member functions shall be explicitly disallowed. See Meyers [6], item 27.

Rationale: Eliminate any surprises that may occur as a result of compiler generated functions. For example, if the assignment operator is unneeded for a particular class, then it should be declared private (and not defined). Any attempt to invoke the operator will result in a compile-time error. On the contrary, if the assignment operator is not declared, then when it is invoked, a compiler-generated form will be created and subsequently executed. This could lead to unexpected results.
Note: If the copy constructor is explicitly disallowed, the assignment operator should be as well. 

4.13 Functions
4.13.1 Function Declaration, Definition and Arguments 

AV Rule 110
Functions with more than 7 arguments will not be used.
Rationale: Functions having long argument lists can be difficult to read, use, and maintain. Functions with too many parameters may indicate an under use of objects and abstractions.
Exception: Some constructors may require more than 7 arguments. However, one should consider if abstractions are being underused in this scenario. 

AV Rule 112
Function return values should not obscure resource ownership.
Rationale: Potential source of resource leaks. 

4.13.2 Return Types and Values 

AV Rule 113 (MISRA Rule 82, Revised)
Functions will have a single exit point.
Rationale: Numerous exit points tend to produce functions that are both difficult to understand and analyze.
Exception: A single exit is not required if such a structure would obscure or otherwise significantly complicate (such as the introduction of additional variables) a function’s control logic. Note that the usual resource clean-up must be managed at all exit points. 

AV Rule 122
Trivial accessor and mutator functions should be inlined.
Rationale: Inlining short, simple functions can save both time and space. 

4.15 Declarations and Definitions 

AV Rule 137 (MISRA Rule 23)
All declarations at file scope should be static where possible. 

4.16 Initialization 

AV Rule 142 (MISRA Rule 30, Revised)
All variables shall be initialized before use.
Rationale: Prevent the use of variables before they have been properly initialized.
Exception: Exceptions are allowed where a name must be introduced before it can be initialized (e.g. value received via an input stream). 

AV Rule 143
Variables will not be introduced until they can be initialized with meaningful values.
Rationale: Prevent clients from accessing variables without meaningful values. 

4.17 Types 

AV Rule 148
Enumeration types shall be used instead of integer types (and constants) to select from a limited series of choices.
Note: This rule is not intended to exclude character constants (e.g. ‘A’, ‘B’, ‘C’, etc.) from use as case labels.
Rationale: Enhances debugging, readability and maintenance. Note that a compiler flag (if available) should be set to generate a warning if all enumerators are not present in a switch statement. 

4.19 Variables 

AV Rule 152
Multiple variable declarations shall not be allowed on the same line.
Rationale: Increases readability and prevents confusion.

4.21 Operators 

AV Rule 162
Signed and unsigned values shall not be mixed in arithmetic or comparison operations.
Rationale: Mixing signed and unsigned values is error prone as it subjects operations to numerous arithmetic conversion and integral promotion rules. 

AV Rule 163
Unsigned arithmetic shall not be used.
Rationale: Over time, unsigned values will likely be mixed with signed values thus violating AV Rule 162.

4.22 Pointers & References 

AV Rule 175
A pointer shall not be compared to NULL or be assigned NULL; use plain 0 instead.
Rationale: The NULL macro is an implementation-defined C++ null pointer constant that has been defined in multiple ways including 0, 0L, and (void*)0. Due to C++’s stronger type-checking, Stroustrup [2] advises the use plain 0 rather than any suggested NULL macro.

4.24 Flow Control Structures 

AV Rule 189 (MISRA Rule 56)
The goto statement shall not be used.
Rationale: Frequent use of the goto statement tends to lead to code that is both dif read and maintain.
Exception: A goto may be used to break out of multiple nested loops provided the alternative would obscure or otherwise significantly complicate the control logic. 

AV Rule 190 (MISRA Rule 57)
The continue statement shall not be used. 

AV Rule 191 (MISRA Rule 58)
The break statement shall not be used (except to terminate the cases of a switch statement).
Exception: The break statement may be used to “break” out of a single loop provided the alternative would obscure or otherwise significantly complicate the control logic. 

AV Rule 200
Null initialize or increment expressions in for loops will not be used; a while loop will be used instead.
Rationale: A while loop provides a more natural representation. 

4.26 Memory Allocation 

AV Rule 206 (MISRA Rule 118, Revised)
Allocation/deallocation from/to the free store (heap) shall not occur after initialization. Note that the “placement” operator new(), although not technically dynamic memory, may only be used in low-level memory management routines.
Rationale: Repeated allocation (new/malloc) and deallocation (delete/free) from the free store/heap can result in free store/heap fragmentation and hence non-deterministic delays in free store/heap access. 

4.28 Portable Code 
4.28.5 Pointer Arithmetic 

AV Rule 215 (MISRA Rule 101)
Pointer arithmetic will not be used. 

4.29 Efficiency Considerations

AV Rule 216
Programmers should not attempt to prematurely optimize code. See Meyers [7], item 16.
Rationale: Early focus on optimization can result in sacrificing the clarity and generality of modules that will not be the true bottlenecks in the final system.
Premature optimization is the root of all evil – Donald Knuth
Note: This rule does not preclude early consideration of fundamental algorithmic and data structure efficiencies.