The classic example is a macro to calculate the maximum of two value:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
Now lets "call" the macro like this:
int x = 5;
int y = 7;
int z = MAX(x++, y++);
Now if MAX
was a normal function, we would expect that x
and y
would be incremented once, right? However because it's a macro the "call" is replaced like this:
int z = ((x++) > (y++) ? (x++) : (y++));
As you see, the variable y
will be incremented twice, once in the condition and once as the end-result of the ternary operator.
This is the result of an expression with side-effects (the post-increment expression) and a macro expansion.
On a related note, there are also other dangers with macros. For example lets take this simple macro:
#define MUL_BY_TWO(x) (x * 2)
Looks simple right? But now what if we use it like this:
int result = MUL_BY_TWO(a + b);
That will expand like
int result = (a + b * 2);
And as you hopefully knows multiplication have higher precedence than addition, so the expression a + b * 2
is equivalent to a + (b * 2)
, probably not what was intended by the macro writer. That is why arguments to macros should be put inside their own parentheses:
#define MUL_BY_TWO(x) ((x) * 2)
Then the expansion will be
int result = ((a + b) * 2);
which is probably correct.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…