The dangers of Macros
Another developer came to me with a problem today that he couldn't figure out. He couldn't believe what he was seeing in the debugger and needed a second set of eyes. He had a line of code like the following;
return max( eRetVal, GetNumber() );</code>
While debugging, he noticed that he was stepping into the GetNumber() method twice, and in his code, it had side-effects. We both puzzled over it for awhile. We looked at the disassembly and sure enough, it was getting called twice, but why? Then it hit me, max is a macro, not a function. If you go to the definition of max, you find;
#ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif</code>
So, if you expand that macro out, the original code gets compiles as;
return (((eRetVal) > (GetNumber()) ? (eRetVal) : (GetNumber());</code>
Once the macro is expanded, it is easy to see why the method is called twice. Obviously I have not being doing enough C++ lately. There was a time when I would have seen that immediately as it is the classic example, but I have been working in .NET so long now that I am forgetting all of the little ways that C++ can bite you.