How to write code as the best programmers at NASA 10 crucial principles

The programmers at NASA have one of the most complicated jobs in the IT world. Their work is tightly connected with the highest level of safety concerns, as they create apps crucial for their missions, and any mistake can cost a lot.


The principles and regulations are very important when it comes to such level of responsibility. The rules they use penetrate every aspect of software development, and the specifications are usually profound.

If you are familiar with IT, at least a little bit, you might know it is hard to establish a great programming standard. However, NASA has a Jet Propulsion Laboratory (JPL) that adheres to the number of code guidelines, called “The Power of Ten–Rules for Developing Safety Critical Code”.


This guide is mostly concentrated on C programming languages, as JPL has a long and time-proven history of using these languages. However, these rules can adjust in a good way to other coding languages.


NASA’s 10 strict guidelines for writing mission-crucial code:

The rules are mandatory, as they can be life-saving in certain situations. That’s why they are so precise. Though they are uncomfortable and strict, it is better not to violate them in order not to get into a fatal situation that could have been avoided.

  1. Earth, code1. Limit all code to very basic control flow constructions – never use goto statements, neither setjmp/longjmp constructs, nor direct/indirect recursion.


  2. 2. Each and every loop needs to have a fixed upper-bound. It should be easily possible for a checking tool to provide statistical evidence that a preset upper-bound on the amount of iterations of a loop can’t be exceeded. If the loop-bound fails to be supported statistically, the rule is believed to be violated.


  3. 3. Never utilize dynamic memory allocation after the initialization process.


  4. 4. No function should exceed the amount of what can be printed on a single sheet of paper in a standard reference format with one line as statement and one line as declaration. Normally, this should not go beyond 60 lines of code per function.


  5. 5. The density of code’s assertion must be in average equal to a minimum of 2 assertions per function. Assertions are used to check for extraordinary conditions that should never appear in real-life processes. Assertions should never have any side-effects and must be identified as Boolean tests. If an assertion fails, an explicit recovery action must be taken, e.g., by sending back a failure-condition to the caller of the function that performs the failing assertion. Any assertion that can be proven by static checking tool that it can never fail or never hold - breaks this rule (I.e., it is not possible to satisfy the rule by providing useless “assert(true)” statements).


  6. 6. Different objects of data must be stated at the smallest possible level of scope.


  7. 7. The return value of non-void functions must be approved and checked by each calling function, and then the truthfulness of indicators must be checked within each function.


  8. 8. The usage of the preprocessor can be only as the inclusion of header files and simple macro definitions. Any of the following are prohibited: token pasting, variable argument lists (ellipses), and recursive macro calls. Each and every macro should expand into complete syntactic unit. The use of conditional compilation directives is usually vague as well, but is impossible to always be avoided. It implies that the instances of justification for more than one or two conditional compilation directives should be as rare as possible, even in large software development efforts, exceeding the regular boilerplate that avoids multiple inclusion of the same header file. Each such use should be flagged or emphasized by a tool-based checker and justified in the code.


  9. 9. The usage of pointers should be limited. Particularly, no more than one level of dereferencing is possible. Pointer dereference operations must not be concealed in macro definitions or within typedef declarations. Function pointers are prohibited.


  10. 10. All code must be compiled, from the first day of development, having all the compiler warnings turned on at the compiler’s most pedantic configuration. All code must compile with these configuration without any warnings. All code must be checked on a daily basis having one minimum, but better more than one, state-of-the-art static source code analyzer. All the code should successfully go through the analyses with no warnings.

The rules are mandatory, as they can be life-saving in certain situations. That’s why they are so precise. Though they are uncomfortable and strict, it is better not to violate them in order not to get into a fatal situation that could have been avoided.