Synopsis: | #define macros shall only be used for symbolic constants. They shall not be used for function like macros if a function can be written to accomplish the same task. |
Language: | C |
Severity Level: | 2 |
Category: | Preprocessing Directives |
Description: |
Justification Macros might be convenient for the program writer but is confusing for all program readers. If performance is important, one can consider to use the "inline" keyword to hint the compiler to substitute the code of the function into its caller (just like function like macros do). Note that most compilers nowadays are much better in deciding whether to inline or not to gain performance. Note that this doesn't hold for all compilers. Exceptions Some functionality can only be implemented by using macros. If the macro definition contains one of the following constructs this rule is not violated:
Example 1 #define UINT unsigned int /* WRONG typedef should be used */ #define BEGIN { /* WRONG */ #define END } /* WRONG */ BEGIN /* WRONG */ int x = y; END /* WRONG */ Example 2 typedef unsigned long CCBB_ulong; /* RIGHT */ #define MAGIC 1.234 /* RIGHT */ Example 3 #define LOG_ERROR(errortext) \ /* RIGHT, using __LINE__ and __FILE__ */ log ("Error occurred at line %d in file %s: %s\n", \ __LINE__, __FILE__, errortext) #define WARN_IF(expr) \ /* RIGHT, stringification */ if(expr) \ { \ log("Warning: " #expr " was TRUE"); \ } |