2012-10-18 97 views
5

给出以下代码:GCC与视觉工作室宏扩展

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) 
} 

视觉工作室2010具有以下预处理器输出(省略一些空白行):

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

}  

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

    doSomething(1,2,3);  
} 

而GCC 4.2给出了下面的:

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 
} 

我不确定哪个是标准的,但我希望它像视觉螺柱一样工作io正在工作。有没有一种方法来重构代码,使其在编译器中以这种方式工作?

+1

通常当VS和gcc不同,它是海湾合作委员会这是正确的。 –

+0

这是Visual C++预处理器中的一个已知错误:它在重新扫描之前不扩展宏。 gcc的行为是正确的。 –

+0

感谢您提供的所有答复......就提供的解决方案而言,我想我简化了我的例子,并且无法让他们工作。我发现了另一种解决方法,但这并不是说明这个普遍问题,所以我会在这里省略它。 – user109078

回答

1

逗号需要特殊处理的,当你另一个宏中使用它们。

这应该工作:

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

你耽误ONE正在把它变成像函数本身的宏立即更换。

你可以看到这避免与BOOST_PP_COMMA_IFboost documentation site更多的例子。

3

另一种可能性是圆括号的参数,所以它不会成为3个参数替代:

#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根据该规范是正确的。