I have started reading Effective C++ and at some point in item 2, the following is mentioned:
// call f with the maximum of a and b
#define CALL_WITH_MAX(a, b) f((a) > (b) ? (a) : (b))
...
int a = 5, b = 0;
CALL_WITH_MAX(++a, b); // a is incremented twice
CALL_WITH_MAX(++a, b+10); // a is incremented once
Here, the number of times that a is incremented before calling f
depends on what it is being compared with!
Indeed, if I use a simple print statement in f
, 7 gets printed in the first call, but I cannot for the life of me figure out why. Am I missing something obvious?
The compiler replaces the macros with exactly what you pass in, verbatim. So you end up with
int a = 5, b = 0;
f((++a) > (b) ? (++a) : (b));
f((++a) > (b+10) ? (++a) : (b+10));
Use g++ -E myprog.cpp
(replace g++
with whatever-your-compiler-is
if you are not using g++
) - it works on ALMOST all compilers, it will produce the actual stuff after preprocessing.
And this is a great example of why you shouldn't use macros to do function-type stuff.
You'd get much more of what you (probably) expect if you were to use an inline function:
inline void CallWithMax(int a, int b)
{
f((a) > (b) ? (a) : (b));
}
Any decent compiler should be able to do this AT LEAST as efficient as a macro, with the added advantage that your a
and b
are evaluated once in the calling code, and nothing "weird" happens.
You can also step through a inline function if you build your code with debug symbols, so if you want to see what value a
and b
actually are inside the function, you can do that. Macros, because they expand into the original place in the source code, so you can't really see what's going on inside.