Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preprocessor macros as parameters to other macros

The following C++ code compiles and works as the programmer intended on GCC (4.0.4)

#define FOO(x,y,z) ((x)*(y)*(z))
#define BAR(x) FOO(x,1)
#define BAZ 3,7

int main()
{
    return BAR(BAZ); /* interpreted as return ((3)*(7)*(1)); */
}

However, the macros cause an error on Microsoft Visual C++ Express 2010:

main.cpp(7): warning C4003: not enough actual parameters for macro 'FOO'
main.cpp(7): error C2059: syntax error : ')'

The issue seems to be that the Microsoft compiler, while handling the BAR macro internally, does not expand the BAZ macro to parameters that could be used as two separate parameters to macro FOO.

According to the standard, which compiler handles the situation correctly?

like image 627
otto Avatar asked May 21 '12 11:05

otto


1 Answers

According to 16.3.4 of ISO/IEC 14882:2003 (C++ Stardard) macro expansion is performed as follows:

  1. Macro invocation is replaced with the macro's replacement list (the body) where each parameter name (unless it is affected by # or ##) is substituted with a complete macro expansion of corresponding argument specified in macro invocation.
  2. The result of step 1 is rescanned. If there are more macro invocations in it (except those already expanded getting the text under consideration), they are expanded according to the same procedure recursively.

The sequence of steps for the code you specified is:

  1. BAR(BAZ)
  2. FOO(3,7,1)
  3. ((3)*(7)*(1))

So GCC is right, and VC is not. But the error which VC complains about is that FOO has 3 arguments and BAR specifies only 2 of them. VC apparently tries to catch errors as soon as possible and goes a bit too far in it.

like image 82
Alex Bakulin Avatar answered Sep 19 '22 19:09

Alex Bakulin