Why C macros lead to unobvious bugs

Very simple example of incorrect macro usage is shown below:

#define MULTIPLE_TWO(x) x * 2
int a = MULTIPLE_TWO(1 + 0)
/* a == ??? */

Inexperienced C programmer may assume that a should equal 2 here, but that's not the way macros work in C language.

When you use macro, preprocessor will literally replace every occurrence of the macro with it's definition, so in the previous example it will become:

int a = 1 + 0 * 2;

So a is 1, not 2.

To avoid such errors you should guard everything with parentheses (i.e. macro "body" and all macro arguments). It should go like this:

#define MULTIPLE_TWO(x) ((x) * 2)
int a = MULTIPLE_TWO(1 + 0);
/* Same as:
a = ((1 + 0) * 2);
which is what reader expects from
macro name */

For simple examples it's easy to figure out which operations have higher priority, but when you deal with bit operations, it will be mess (who remembers, what is higher priority of ^ vs | vs <<? I don't 🤔), so just use parentheses!

p.s. As an exercise, think how to fix this macro to avoid triple increment and still calculate x+x^2 function in this case:

#define MY_MACRO(x) x + x * 2
int a = 0;
int b = MY_MACRO(++a);
/* a should be 1 */


Back