6

给出以下代码:

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 具有以下预处理器输出(省略一些空行):

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
}

我不确定哪个是标准的,但我希望它像 Visual Studio 一样工作。有没有办法重构代码以便它在两个编译器中都以这种方式工作?

4

2 回答 2

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

于 2012-10-18T22:30:46.837 回答
1

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

这应该有效:

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

ONE可以通过将其转换为宏本身的功能来延迟立即被替换。

BOOST_PP_COMMA_IF您可以在boost 文档站点上看到更多避免这种情况的示例。

于 2012-10-18T22:23:08.770 回答