2012-10-18 140 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根據該規範是正確的。