Search code examples
cmisracppcheck

Confirmation for inappropriate choice of macro definition name in C


Is there a relable reference that can confirm that using a name of a number as macro (in C) is inappropriate ?

Consider the follwing example:

#define ZERO (0)
#define ONE (1)
#define TWO (2)
#define THREE (3)
#define FOUR (4)
// ... etc 

Solution

  • If you are asking about these very macros specifically... then the answer is to use neither 1 nor ONE. As usual, common sense will get you very far: use a named constant which states a meaningful name communicating to the reader what that constant is to be used for. Not what number it contains.

    If you are moving and pack your shoes in a cardboard box, you would write "shoes" on the box right? Not "ten" because there are ten shoes in the box.

    That is:

    // GOOD
    #define SIZE 5
    size_t x = SIZE;
    
    // BAD
    size_t x = 5; // size
    
    // BAD
    #define FIVE 5
    size_t x = FIVE; // size
    

    The first bad example is bad because there's no explanation where that number came from - the programmer seems to just have pulled it out of a hat. These are called "magic numbers" and are widely recognized as bad practice.

    The comments in both bad examples became necessary just because the code isn't self-documenting. We wouldn't have needed that comment if a macro with a sensible name was used


    As far as MISRA is concerned, the relevant rule is MISRA C:2012 20.7 telling you to always wrap function-like macros inside parenthesis. Since this is already fundamental good practice in C, it should come as no surprise to C programmers.

    But these are not function-like macros but macro constants. We can then note that the same MISRA rule also mentions this in the rationale:

    If a macro paramete ris not being used as an expression then the parenthesis are not necessary because no operators are involved

    This also makes perfect sense, because we sometimes want to expand macros and perhaps use them together with # or ## operators, which will not be possible if there's a parenthesis there. So drop the extra parenthesis, it is just harmful clutter.


    Notably, for MISRA compliance, integer constants that are used in a context where they should be unsigned must be written as 5u or 5U.