Aussie AI

Defensive Programming

  • Book Excerpt from "Generative AI in C++"
  • by David Spuler, Ph.D.

Defensive Programming

Defensive programming is a mindset where you assume that everything will go wrong. The user input will be garbage. Anyone else's code will be broken. The operating system intrinsics will fail. And your poor helpless AI needs to keep chugging along.

Many of the high-level types of defensive coding are discussed elsewhere in this book. Good practices that attempt to prevent bugs include: assertions, self-testing code, unit tests, regression tests, check return codes, validate incoming parameter values, exception handling, error logging, debug tracing code, warning-free compilation, memory debugging tools, static analysis tools, document your code, and call your mother on Sunday.

Using Compiler Errors for Good, not Evil: One of the advanced types of defensive programming is to intentionally trigger compiler errors that prevent compilation. For example, you can enforce security coding policies:

    #define tmpnam dont_use_tmpnam_please

Or if you are using debug wrappers for some low-level system functions, you can enforce that:

    #define memset please_use_memset_wrapper

Politeness is always required. You don't want your colleagues going home crying.

Defensive Coding Style Policies: You might want to consider some specific bug-prevention coding styles, for defensive programming, maintainability, and general reliability. Some examples might be:

  • All variables must be initialized when declared. Don't want to see this anymore: int x;
  • All switch statements need a default clause.
  • Null the pointer after every delete. You can define a macro to help.
  • Null the pointer after every free. If you use a debug wrapper for free, make it pass-by-reference and NULL the pointer's value insider the wrapper function.
  • Null the file pointer after fclose. Also can be nulled by a wrapper function.
  • Unreachable code should be marked as such with an assertion (a special type).
  • Prefer inline functions to preprocessor macros.
  • Define numeric constants using const rather than #define.
  • Validate enum variables are in range. Add a dummy EOL item at the end of an enum list, which can be used as an upper-bound to range-check any enum has a valid value. Define a self-test macro to range-check the value.
  • Use [[nodiscard]] attributes for functions. All of them.
  • Start different enums at different numbers (e.g. token numbers start at 10,000 and some other IDs start at 200,000), so that they can't get mixed up, even if they end up in int variables. And you'll need a bottom and top value to range-check their validity. You have to remove the commas from these numbers, though!
  • All allocated memory must be zeroed. This might be a policy for each coder, or it could be auto-handled by intercepting the new operator and malloc/calloc into debug wrappers, and only returning cleared memory.
  • Constructors should use memset to zero their own memory. This seems like bad coding style in a way, but how many times have you forgotten to initialize a data member in a constructor?
  • Zero means “not set” for every flag, enum, status code, etc. This is a policy supporting the “zero all memory” defensive idea.

Assume failures will happen: Plan ahead to make failures easier to detect and debug (supportability!), even when they happen in production code:

  • Use extra messages in assertions, and make them brief but useful.
  • If an assertion keeps failing in testing, or fails in production for users, change it to more detailed self-checking code that emits a more detailed error.
  • Add unique code numbers to error messages to make identifying causes easier (supportability).
  • Separately check different error occurrences. Don't use only one combined assertion: assert(s && *s);
  • Review assertions for cases where lazy code jockeys have used them to check return codes (e.g. file not found).

 

Next:

Up: Table of Contents

Buy: Generative AI in C++: Coding Transformers and LLMs

Generative AI in C++ The new AI programming book by Aussie AI co-founders:
  • AI coding in C++
  • Transformer engine speedups
  • LLM models
  • Phone and desktop AI
  • Code examples
  • Research citations

Get your copy from Amazon: Generative AI in C++