给出以下代码:
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一样工作。有没有办法重构代码,以便它在两个编译器中以这种方式工作?
答案 0 :(得分: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是正确的。
答案 1 :(得分:1)
当你在另一个宏中使用它们时,逗号需要特殊处理。
这应该有效:
#define ONE() 1,2,3
#define TWO(ARG) doSomething(ARG());
#define THR(ARG) TWO(ARG)
您可以通过将其变为像宏本身一样的功能来立即替换ONE
。
您可以在boost documentation site上看到更多使用BOOST_PP_COMMA_IF
来避免此问题的示例。