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.

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

 

 

 

 

 

This page intentionally left blank
TABLE OF CONTENTS

 

1      Introduction. 7

2      Referenced Documents. 8

3      General Design. 10

3.1       Coupling & Cohesion. 11

3.2       Code Size and Complexity. 12

4      C++ Coding Standards. 13

4.1       Introduction. 13

4.2       Rules. 13

4.2.1        Should, Will, and Shall Rules. 13

4.2.2        Breaking Rules. 13

4.2.3        Exceptions to Rules. 14

4.3       Terminology. 14

4.4       Environment 17

4.4.1        Language. 17

4.4.2        Character Sets. 17

4.4.3        Run-Time Checks. 18

4.5       Libraries. 19

4.5.1        Standard Libraries. 19

4.6       Pre-Processing Directives. 20

4.6.1        #ifndef and #endif  Pre-Processing Directives. 20

4.6.2        #define Pre-Processing Directive. 21

4.6.3        #include Pre-Processing Directive. 21

4.7       Header Files. 22

4.8       Implementation Files. 23

4.9       Style. 23

4.9.1        Naming Identifiers. 24

4.9.1.1     Naming Classes, Structures, Enumerated types and typedefs. 25

4.9.1.2     Naming Functions, Variables and Parameters. 26

4.9.1.3     Naming Constants and Enumerators. 26

4.9.2        Naming Files. 26

4.9.3        Classes. 27

4.9.4        Functions. 27

4.9.5        Blocks. 28

4.9.6        Pointers and References. 28

4.9.7        Miscellaneous. 28

4.10     Classes. 29

4.10.1      Class Interfaces. 29

4.10.2      Considerations Regarding Access Rights. 29

4.10.3      Member Functions. 29

4.10.4      const Member Functions. 30

4.10.5      Friends. 30

4.10.6      Object Lifetime, Constructors, and Destructors. 30

4.10.6.1       Object Lifetime. 30

4.10.6.2       Constructors. 31

4.10.6.3       Destructors. 32

4.10.7      Assignment Operators. 33

4.10.8      Operator Overloading. 33

4.10.9      Inheritance. 34

4.10.10        Virtual Member Functions. 37

4.11     Namespaces. 38

4.12     Templates. 39

4.13     Functions. 40

4.13.1      Function Declaration, Definition and Arguments. 40

4.13.2      Return Types and Values. 41

4.13.3      Function Parameters (Value, Pointer or Reference) 42

4.13.4      Function Invocation. 42

4.13.5      Function Overloading. 43

4.13.6      Inline Functions. 43

4.13.7      Temporary Objects. 44

4.14     Comments. 44

4.15     Declarations and Definitions. 46

4.16     Initialization. 47

4.17     Types. 48

4.18     Constants. 48

4.19     Variables. 49

4.20     Unions and Bit Fields. 50

4.21     Operators. 51

4.22     Pointers & References. 52

4.23     Type Conversions. 54

4.24     Flow Control Structures. 56

4.25     Expressions. 58

4.26     Memory Allocation. 59

4.27     Fault Handling. 59

4.28     Portable Code. 60

4.28.1      Data Abstraction. 60

4.28.2      Data Representation. 60

4.28.3      Underflow/Overflow.. 61

4.28.4      Order of Execution. 61

4.28.5      Pointer Arithmetic. 61

4.29     Efficiency Considerations. 62

4.30     Miscellaneous. 62

5      Testing. 63

5.1.1        Subtypes. 63

5.1.2        Structure. 63

Appendix A.. 66

Appendix B (Compliance) 142

 


Table 1. Change Log

Revision
ID

Document
Date

Change
Authority

Affected
Paragraphs

Comments

0001 Rev B

Oct 2005

K. Carroll

All

Original

0001 Rev C

Nov 2005

K. Carroll

Change log - Added

Add change log.

 

 

 

Section 1, point 3

Rule 52

Rule 76

Rule 91

Rule 93

Rule 129

Rule 167

Rule 218

Appendix A, Rule 3

Table 2

Corrected spelling errors.

 

 

 

Rule 159 - clarify that "unary &" is intended.

Both binary and unary forms of "&" exist. Clarification is added to specify that the rule is concerned with the unary form.

 

 

 

Rule 32 - clarification of the scope of the rule. Also, example added in appendix for rule 32.

The rule does not apply to a particular partitioning of template classes and functions.

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. Consequently, the rules contained in this document are required for Air Vehicle C++ development[1] and recommended for non-Air Vehicle C++ development.

 

As indicated above, portions of Air Vehicle (AV) code will be developed in C++.  C++ was designed to support data abstraction, object-oriented programming, and generic programming while retaining compatibility with traditional C programming techniques.  For this reason, the AV Coding Standards will focus on the following:

 

1.      Motor Industry Software Reliability Association (MISRA) Guidelines For The Use Of The C Language In Vehicle Based Software,

 

2.      Vehicle Systems Safety Critical Coding Standards for C, and

 

3.      C++ language-specific guidelines and standards.

 

The MISRA Guidelines were written specifically for use in systems that contain a safety aspect to them.  The guidelines address potentially unsafe C language features, and provide programming rules to avoid those pitfalls. The Vehicle Systems Safety Critical Coding Standards for C, which are based on the MISRA C subset, provide a more comprehensive set of language restrictions that are applied uniformly across Vehicle Systems safety critical applications.  The AV Coding Standards build on the relevant portions of the previous two documents with an additional set of rules specific to the appropriate use C++ language features (e.g. inheritance, templates, namespaces, etc.) in safety-critical environments.

 

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. In essence, programs are written in a “safer” subset of a superset.

2      Referenced Documents

 

1.      ANSI/IEEE Std 754, IEEE Standard for Binary Floating‑Point Arithmetic, 1985.

 

2.      Bjarne Stroustrup. The C++ Programming Language, 3rd Edition. Addison-Wesley, 2000.

 

3.      Bjarne Stroustrup. Bjarne Stroustrup's C++ Glossary.

 

4.      Bjarne Stroustrup. Bjarne Stroustrup's C++ Style and Technique FAQ.

 

5.      Barbara Liskov. Data Abstraction and Hierarchy, SIGPLAN Notices, 23, 5 (May, 1988).

 

6.      Scott Meyers. Effective C++: 50 Specific Ways to Improve Your Programs and Design, 2nd Edition. Addison-Wesley, 1998.

 

7.      Scott Meyers. More Effective C++: 35 New Ways to Improve Your Programs and Designs. Addison-Wesley, 1996.

 

8.      Motor Industry Software Reliability Association. Guidelines for the Use of the C Language in Vehicle Based Software, April 1998.

 

9.      ISO/IEC 10646‑1, Information technology ‑ Universal Multiple‑Octet Coded Character Set (UCS) ‑ Part 1: Architecture and Basic Multilingual Plane, 1993.

 

10.  ISO/IEC 14882:2003(E), Programming Languages – C++. American National Standards Institute, New York, New York 10036, 2003.

 

11.  ISO/IEC 9899: 1990, Programming languages ‑ C, ISO, 1990.

 

12.  JSF Mission Systems Software Development Plan.

 

13.  JSF System Safety Program Plan. DOC. No. 2YZA00045-0002.

 

14.  Programming in C++ Rules and Recommendations.
Copyright © by Ellemtel Telecommunication Systems Laboratories

Box 1505, 125 25 Alvsjo, Sweden

Document: M 90 0118 Uen,  Rev. C, 27 April 1992.

 

Used with permission supplied via the following statement:

 

Permission is granted to any individual or institution to use, copy, modify and distribute this document, provided that this complete copyright and permission notice is maintained intact in all copies.

 

15.  RTCA/DO-178B, Software Considerations in Airborne Systems and Equipment Certification, December 1992.

 

3      General Design

This coding standards document is intended to help programmers develop code that conforms to safety-critical software principles, i.e., code that does not contain defects that could lead to catastrophic failures resulting in significant harm to individuals and/or equipment. In general, the code produced should exhibit the following important qualities:

 

Reliability: Executable code should consistently fulfill all requirements in a predictable manner.

 

Portability: Source code should be portable (i.e. not compiler or linker dependent).

 

Maintainability: Source code should be written in a manner that is consistent, readable, simple in design, and easy to debug.

 

Testability: Source code should be written to facilitate testability. Minimizing the following characteristics for each software module will facilitate a more testable and maintainable module:

1.      code size

2.      complexity

3.      static path count (number of paths through a piece of code)

 

Reusability: The design of reusable components is encouraged. Component reuse can eliminate redundant development and test activities (i.e. reduce costs).

 

Extensibility: Requirements are expected to evolve over the life of a product. Thus, a system should be developed in an extensible manner (i.e. perturbations in requirements may be managed through local extensions rather than wholesale modifications).

 

Readability: Source code should be written in a manner that is easy to read, understand and comprehend.

 

Note that following the guidelines contained within this document will not guarantee the production of an error-free, safe product. However, adherence to these guidelines, as well as the processes defined in the Software Development Plan [12], will help programmers produce clean designs that minimize common sources of mistakes and errors.

 


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.

Note:    Section 4.2.1 defines should and shall rules as well the conditions under which deviations from should or shall rules are allowed.

AV Rule 2   

There shall not be any self-modifying code.

 

Rationale: Self-modifying code is error-prone as well as difficult to read, test, and maintain.

AV Rule 3   

All functions shall have a cyclomatic complexity number of 20 or less. 

 

Rationale: Limit function complexity. See AV Rule 3 in Appendix A for additional details.

Exception: A function containing a switch statement with many case labels may exceed this limit.

Note:   Section 4.2.1 defines should and shall rules as well the conditions under which deviations from should or shall rules are allowed.

4      C++ Coding Standards

4.1           Introduction

The purpose of the following rules and recommendations is to define a C++ programming style that will enable programmers to produce code that is more:

·        correct,

·        reliable, and

·        maintainable.

In order to achieve these goals, programs should:

·        have a consistent style,

·        be portable to other architectures,

·        be free of common types of errors, and

·        be understandable, and hence maintainable, by different programmers.

4.2           Rules

4.2.1        Should, Will, and Shall Rules

There are three types of rules: should, will, and shall rules.  Each rule contains either a “should”, “will” or a “shall” in bold letters indicating its type.

·        Should rules are advisory rules.  They strongly suggest the recommended way of doing things. 

·        Will rules are intended to be mandatory requirements. It is expected that they will be followed, but they do not require verification. They are limited to non-safety-critical requirements that cannot be easily verified (e.g., naming conventions).

·        Shall rules are mandatory requirements.  They must be followed and they require verification (either automatic or manual).

4.2.2        Breaking Rules

AV Rule 4   

To break a “should” rule, the following approval must be received by the developer:

·        approval from the software engineering lead (obtained by the unit approval in the developmental CM tool)

AV Rule 5   

To break a “will” or a “shall” rule, the following approvals must be received by the developer:

·        approval from the software engineering lead (obtained by the unit approval in the developmental CM tool)

·        approval from the software product manager (obtained by the unit approval in the developmental CM tool)

AV Rule 6   

Each deviation from a “shall” rule shall be documented in the file that contains the deviation). Deviations from this rule shall not be allowed, AV Rule 5 notwithstanding.

4.2.3        Exceptions to Rules

Some rules may contain exceptions. If a rule does contain an exception, then approval is not required for a deviation allowed by that exception

AV Rule 7   

Approval will not be required for a deviation from a “shall” or “will” rule that complies with an exception specified by that rule.

4.3           Terminology

1.      An abstract base class is a class from which no objects may be created; it is only used as a base class for the derivation of other classes. A class is abstract if it includes at least one member function that is declared as pure virtual.

 

2.      An abstract data type is a type whose internal form is hidden behind a set of access functions. Objects of the type are created and inspected only by calls to the access functions. This allows the implementation of the type to be changed without requiring any changes outside the module in which it is defined.

 

3.      An accessor function is a function which returns the value of a data member.

 

4.      A catch clause is code that is executed when an exception of a given type is raised. The definition of an exception handler begins with the keyword catch.

 

5.      A class is a user-defined data type which consists of data elements and functions which operate on that data. In C++, this may be declared as a class; it may also be declared as a struct or a union. Data defined in a class is called member data and functions defined in a class are called member functions.

 

6.      A class template defines a family of classes. A new class may be created from a class template by providing values for a number of arguments. These values may be names of types or constant expressions.

 

7.      A compilation unit is the source code (after preprocessing) that is submitted to a compiler for compilation (including syntax checking).

 

8.      A concrete type is a type without virtual functions, so that objects of the type can be allocated on the stack and manipulated directly (without a need to use pointers or references to allow the possibility for derived classes). Often, small self-contained classes. [3]

 

9.      A constant member function is a function which may not modify data members.

 

10.  A constructor is a function which initializes an object.

 

11.  A copy constructor is a constructor in which the first argument is a reference to an object that has the same type as the object to be initialized.

 

12.  Dead code is “executable object code (or data) which, as a result of a design error cannot be executed (code) or used (data) in an operational configuration of the target computer environment and is not traceable to a system or software requirement.” [8]

 

13.  A declaration of a variable or function announces the properties of the variable or function; it consists of a type name and then the variable or function name.  For functions, it tells the compiler the name, return type and parameters.  For variables, it tells the compiler the name and type.

 

int32   fahr;

int32   foo ();

 

14.  A default constructor is a constructor which needs no arguments.

 

15.  A definition of a function tells the compiler how the function works.  It shows what instructions are executed for the function.

 

int32   foo ()

{

    // Statements

}

 

16.  An enumeration type is an explicitly declared set of symbolic integer constants. In C++ it is declared as an enum.

 

17.  An exception is a run-time program anomaly that is detected in a function or member function. Exception handling provides for the uniform management of exceptions.

 

18.  A forwarding function is a function which does nothing more than call another function.

 

19.  A function template defines a family of functions. A new function may be created from a function template by providing values for a number of arguments. These values may be names of types or constant expressions.

 

20.  An identifier is a name which is used to refer to a variable, constant, function or type in C++.   When necessary, an identifier may have an internal structure which consists of a prefix, a name, and a suffix (in that order).

 

21.  An iterator is an object that con be used to traverse a data structure.

 

22.  A macro is a name for a text string which is defined in a #define statement. When this name appears in source code, the compiler replaces it with the defined text string.

 

23.  Multiple inheritance is the derivation of a new class from more than one base class.

 

24.  A mutator function is a function which sets the value of a data member.

 

25.  The one definition rule - there must be exactly one definition of each entity in a program. If more than one definition appears, say because of replication through header files, the meaning of all such duplicates must be identical. [3]

 

26.  An overloaded function name is a name which is used for two or more functions or member functions having different argument types.

 

27.  An overridden member function is a member function in a base class which is re-defined in a derived class.

 

28.  A built-in data type is a type which is defined in the language itself, such as int.

 

29.  Protected members of a class are member data and member functions which are accessible by specifying the name within member functions of derived classes.

 

30.  Public members of a class are member data and member functions which are accessible everywhere by specifying an instance of the class and the name.

 

31.  A pure virtual function is one with an initializer = 0 in its declaration.  Making a virtual function pure makes the class abstract.  A pure virtual function must be overridden in at least one derived class.

 

32.  A reference is another name for a given variable. In C++, the ‘address of’ (&) operator is used immediately after the data type to indicate that the declared variable, constant, or function argument is a reference.

 

33.  The scope of a name refers to the context in which it is visible. [Context, here, means the functions or blocks in which a given variable name can be used.]

 

34.  A side effect is the change of a variable as a by-product of an evaluation of an expression.

 

35.  A structure is a user-defined type for which all members are public by default.

 

36.  A typedef is another name for a data type, specified in C++ using a typedef declaration.

 

37.  Unqualified type is a type that does not have const or volatile as a qualifier.

 

38.  A user-defined data type is a type which is defined by a programmer in a class, struct, union, or enum definition or as an instantiation of a class template.

 


4.4           Environment

4.4.1        Language

AV Rule 8   

All code shall conform to ISO/IEC 14882:2002(E) standard C++. [10]

 

Rationale: ISO/IEC 14882 is the international standard that defines the C++ programming language. Thus all code shall be well-defined with respect to ISO/IEC 14882. Any language extensions or variations from ISO/IEC 14882 shall not be allowed.

4.4.2        Character Sets

Note that the rules in this section may need to be modified if one or more foreign languages will be used for input/output purposes (e.g. displaying information to pilots).

AV Rule 9  (MISRA Rule 5, Revised)

Only those characters specified in the C++ basic source character set will be used. This set includes 96 characters: the space character, the control characters representing horizontal tab, vertical tab, form feed, and newline, and the following 91 graphical characters:

 

a b c d e f g h i j k l m n o p q r s t u v w x y z

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

0 1 2 3 4 5 6 7 8 9

_ { } [ ] # ( ) < > % : ; . ? * + ­

/ ^ & | ~ ! = , \ " ’

 

Rationale: Minimal required character set.

AV Rule 10          (MISRA Rule 6)

Values of character types will be restricted to a defined and documented subset of ISO 10646‑1. [9]

 

Rationale: 10646‑1 represents an international standard for character mapping. For the basic source character set, the 10646-1 mapping corresponds to the ASCII mapping.

AV Rule 11          (MISRA Rule 7)

Trigraphs will not be used.

Trigraph sequences are three-character sequences that are replaced by a corresponding single character, as follows:

 

Alternative

Primary

alternative

primary

alternative

primary

??=

#

??(

[

??<

{

??/

\

??)