The power of ten are a set of coding standards adopted by NASA to ensure that their software in production (outer space) is safe, robust, and reliable, especially in C and other memory-unsafe languages.

From this great video by Low Level Learning.

The ten standards are:

  • Simple control flow
    • No goto, setjump, longjump, or recursion.
    • Recursion can lead to runaway code that is *difficult to analyse.
  • Limit all loops
    • Fixed upper bound to loops. There must be a finite end case; the code will be bound by a hard integer upper limit.
    • If the loop doesn’t finish, then this condition is considered violated.
  • Don’t use the heap
    • No malloc or free. Exclusively use memory on the stack.
    • This is due to a large number of problems related to using the heap:
      • Memory leak
      • Use-after-frees
      • Heap overflows
      • Heap exhaustion
    • Setting an upper limit on the stack memory allows us to predict how much memory our program will take and eliminate the problems above.
  • Limit function size
    • Functions should do one thing. It may require sub-functions.
    • Functions should be no longer than 60 lines (i.e., no more than the size of a printer page).
    • This makes unit tests easy to implement.
    • If the function has 400 lines and several layers of nesting, the code is poorly structured and not well thought out.
  • Data hiding
    • To hide internal object details, restrict the data access to class members. This maintains data integrity.
    • Declare variables at the lowest scope possible. This allows us to debug better.
  • Check return values
    • Check all non-void return values.
    • Explicitly cast all return values that are ignored to a void type, i.e., if we don’t need the function’s output.
  • Limit the use of the preprocessor
    • It’s an obfuscation tool “that can destroy code clarity and befuddle many text-based checkers”.
    • Especially conditional compilation #ifndef. If there are 10 different flags that can be changed at compile time, we need to test different build targets.
      • Hard to scale, hard to test!
  • Restrict pointer use
    • No more than one level of dereferencing. Do not dereference in macro or typedef declarations.
    • They’re easy to use incorrectly, but are powerful.
    • This limit forces us to use structs to limit dereferences.
    • Limit function pointers.
  • Be pedantic
    • Compile in pedantic mode. Any possible problem will be flagged.
    • Unit test everything.