Implement a "secure" coding standard on all mission-critical software.
Consistent use of approved coding standards reduces the frequency of common run-time errors and promotes maintainability and re-usability.
2. Examples and Discussion
Coding standards promote readability and maintainability---important features for code that is likely to be used over a period of years or reused on other projects and SWE-061 - Coding Standards in NPR 7150.2
calls for the use of secure coding standards. A quality set of coding standards can improve the quality of code in many other ways as well. The list below specifies a minimal set of standards commonly found in standards for high-reliability software. These rules have been found to reduce the likelihood of run time errors.
Restrict the use of dynamic memory allocation to one-time events at system initialization.
Use the simplest flow control constructs possible, and avoid the use of “go to”, setjump/longjump.
Ensure that all loop constructs have a fixed upper bound, and avoid the use of recursion.
Declare data objects at the lowest scope possible.
Implement logic to check, and possibly act, on the return value of non-void functions.
A complete set of coding standards typically includes best practices, such as strict language adherence and the use of automated tools to identify problems either at compile time or run time. Language-specific guidance, domain-specific guidance, local standards for code organization and commenting, and standard file header format are often specified as well.
Good coding standards have two things in common: (1) they are concise and relevant enough to be easily used by programmers and quality assurance professionals in their daily activities; and (2) they enable the use of automated code checking. The first is important for obvious reasons. A standard that is too cumbersome will quickly fall into disuse. The second is important because it reduces cost and increases the likelihood that violations that would lead to program errors will be caught before deployment.
A draft version of design principles produced by the Marshall Space Flight Center (MSFC) includes guidance on the use and development of coding standards. In keeping with a “keep it simple” approach, the standard had only six mandatory practices applicable across all programming languages and allows the inclusion of language-specific and project-specific aspects. The mandatory practices strongly overlapped with the minimal set above, and the standard made it clear that the fundamental practices were not to be overridden by language-specific standards, which in turn were not to be overridden by project-specific standards. This tiered approach makes it easier for an organization to implement a basic set of standards that may be tailored on a per-project basis. This approach supports a Capability Maturity Model Integration (CMMI) Level 3 and above organization.
JPL has taken a somewhat different approach. All projects are required to identify the coding standards used in the development, but no specific standard is imposed. An institutionally supported C coding standard is available. This standard is broken down into six levels of compliance, each more rigorous than the next. Projects that use the institutional standard must determine the level of compliance appropriate for their project. Projects are allowed to produce their own standard, use an alternative standard, or tailor the institutional standard. Except for a general provision concerning safety-critical software, there are no restrictions on the standards that may be used. This approach also supports a CMMI Level 3 certification.
Specific coding standards in use include JPL's C Coding Standard
, GSFC's C Coding Standard for Flight Software
, and GSFC's C++ Coding Standard for Flight Software
, which is all available in the Software Processes Across NASA (SPAN) library. Another resource for coding standards is Gerard Holzmann's "Power of Ten"
paper. There are a number of static analysis tools that can help verify adherence to coding standards, including VectorCast, Polyspace, and Klocwork.
3.1 NESC inputs
220.127.116.11.1 Coding and Implementation Issues Related to Reliability
Definition of suitable coding standards and conventions: Coding standards and conventions can enhance reliability by considering such issues as:
Policies on dynamic memory allocation in safety-critical systems (generally, it should not be allowed)
“Defensive” coding practices for out of range inputs and response times
Exception handler implementation
Coding to enhance testability and readability
Documentation to support verification
Interrupt versus deterministic timing loop processing for safety-critical software
Policies on allowable interprocess communications mechanisms (e.g., point to point versus publish and subscribe)
Permitted use of dynamic binding (an alternative is static "case statements")
Policies on initialization of variables (some standards prohibit the assignment of dummy values to variables upon initialization in order to enable detection of assignment errors in subsequent execution)
Use of “friend” (C++) or “child” (Ada) declarations to enable testing and evaluation of encapsulated data code during development without requiring the subsequent removal of “scaffold code”.
For object-oriented languages, limitations on levels of inheritance in order to prevent “accidental inheritance” due to the introduction of variables with the same name or variable misspelling.
"During a walk-through of the Galileo Spacecraft System fault protection implementation a possible "deadly embrace" in the flight software was uncovered. A deadly embrace is a continuous software looping operation that may preclude the achievement of an acceptable spacecraft state."