Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gcc vs. visual studio macro expansion

given the following code:

void doSomething(int one, int two, int three)
{
   //something here
}

#define ONE 1,2,3

#define TWO(arg) doSomething(arg);

#define THREE(arg) TWO(arg)

void doSomethingElse()
{
   TWO(ONE)

   THREE(ONE)
}

visual studio 2010 has the following preprocessor output (omitting some blank lines):

void doSomething(int one, int two, int three)
{

}    

void doSomethingElse()
{
   doSomething(1,2,3);

   doSomething(1,2,3);    
}

while gcc 4.2 gives the following:

void doSomething(int one, int two, int three)
{

}    

void doSomethingElse()
{
   doSomething(1,2,3);

myFile.cpp:17:13: error: macro "TWO" passed 3 arguments, but takes just 1 
   TWO
}

I'm not sure which is standard, but I'd like it to work like visual studio is working. Is there a way to refactor the code so that it works this way in both compilers?

like image 849
user109078 Avatar asked Oct 18 '12 01:10

user109078


2 Answers

Another possibility would be parenthesizing the argument so that it doesn't become 3 arguments in the substitution:

#define ONE 1,2,3                                                                                                                                                                                                                                                              
#define TWO_PARENS(arg) doSomething arg;                                                                                                                                                                                                                                       
#define TWO(arg) TWO_PARENS((arg));                                                                                                                                                                                                                                           
#define THREE(arg) TWO_PARENS((arg))
THREE(ONE)          

BTW gcc is right according to the spec.

like image 132
jpalecek Avatar answered Oct 26 '22 23:10

jpalecek


Commas need special handling when you're using them within another macro.

This should work:

#define ONE() 1,2,3
#define TWO(ARG) doSomething(ARG());
#define THR(ARG) TWO(ARG)

You delay ONE being replaced immediately by turning it into function like macro itself.

You can see more examples of avoiding this with BOOST_PP_COMMA_IF on the boost documentation site.

like image 25
Tom Kerr Avatar answered Oct 27 '22 00:10

Tom Kerr