Barr Group FacebookBarr Group TwitterBarr Group LinkedInBarr Group Vimeo

Rules

The following C coding rules relate to the use of preprocessor macros in embedded software:

Rule 6.3.a.) Parameterized macros shall not be used if an inline function can be written to accomplish the same task. (Note: Note that individual functions will be needed to support each base type for comparison.)

Rule 6.3.b.) If parameterized macros are used for some reason, these rules apply:

  1. Surround the entire macro body with parentheses.
  2. Surround each use of a parameter with parentheses.
  3. Use each argument no more than once, to avoid unintended side effects.

Example

// Don’t do this ...
#define MAX(A, B)   ((A) > (B) ? (A) : (B))         

// ... if you can do this instead. 
inline int32_t max(int32_t num1, int32_t num2)           

Note: [C99] formally added the C++ keyword inline to C.

Reasoning

There are a lot of risks associated with the use of preprocessor #defines, and many of them relate to the creation of parameterized macros. The extensive use of parentheses (as shown in the example) is important, but does not eliminate the unintended double increment possibility of a call such as MAX(i++, j++). Other risks of macro misuse include comparison of signed and unsigned data or any test of floating-point data. Making matters worse, macros are invisible at run-time and thus impossible to step into within the debugger. (Note: Of course, inline functions are also invisible at debug time.)

Exceptions

In the case of necessary (and tested, and documented) efficiency, a local exception can be approved. That’s when the second set of rules kicks in.

Enforcement

The avoidance of and safe use of macros shall be enforced during code reviews.

What’s happening and how it’s done. Get in the know.

Sign up for our newsletter today!

Receive free how-to articles, industry news, and the latest info on Barr Group webinars and training courses via email. 

To prevent automated spam submissions leave this field empty.