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

gcc4.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
}

どちらが標準かはわかりませんが、VisualStudioが機能しているように機能させたいと思います。両方のコンパイラでこのように機能するようにコードをリファクタリングする方法はありますか?

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)          

仕様によると、ところで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_IFboost のドキュメント サイトを参照してください。

于 2012-10-18T22:23:08.770 に答える