2013-05-27 60 views
4

調用變量宏M是否合法,其變量參數沒有參數?變量宏,沒有可變參數參數

的相關標準是引用[cpp.replace/4

如果標識符列表中的宏定義不與省略號結束,(參數的個數,包括那些參數由沒有預處理標記)在調用類似函數的宏時應該等於宏定義中的參數個數。否則,調用中的參數應該多於宏定義中的參數(不包括...)。應該有一個終止調用的預處理令牌。

對於沒有非可變參數的參數的情況下,在形式M()調用應該是合法作爲調用有一個參數(由無預處理標記的)。所以有一個比非可變參數多一個參數。

對於具有一個非可變參數的情況,是否應該有一個尾隨,,如M(1,)中引入一個參數,該參數包含無預處理標記用於可變參數?否則,參數的數量將等於非可變參數的數量。即,

#define variadic(x,...) #__VA_ARGS__ 

variadic(1,) // 2 arguments: ok 
variadic(1) // 1 argument: wrong? 

兩個GCC,但是,接受以下測試例:

#include <iostream> 

#define variadic(x,...) #__VA_ARGS__ 

int main() 
{ 
    std::cout << "'" variadic(1) "'" << std::endl; 
} 

,併產生作爲輸出:

'' 

這是非標準行爲?

回答

3

否則,在調用中應該有更多的參數,而不是宏定義中的參數(不包括...)。

這個從標準中提取的非常精華顯示你的代碼不應該是有效的:你有一個參數加上省略號。如果我們按照上述標準的部分,你應該至少有兩個參數。當你寫varidadic(1)時,你只需提供一個參數。您的代碼無效。

順便說一句,鐺產生一個警告:

main.cpp:7:32: warning: must specify at least one argument for '...' parameter of variadic macro [-Wgnu] 
    std::cout << "'" variadic(1) "'" << std::endl; 

和gcc也產生一個警告:

main.cpp:7:32: warning: ISO C99 requires rest arguments to be used [enabled by default] 
    std::cout << "'" variadic(1) "'" << std::endl; 

因爲這可能是一個麻煩的程序員,因爲程序員的意圖是容易猜到,他們都認爲variadic(1)相當於variadic(1,)

+0

應該做些什麼來消除這些警告? –

+0

@ rr-解決問題:要麼一致地傳遞兩個參數,要麼讓宏使用「至少0」參數而不是「至少一個」。 – Morwenn

+1

正在改變'#define variadic(x,...)#__ VA_ARGS__'→'#define variadic(...)#__ VA_ARGS__'是否足夠?(從OP的帖子中得到的例子) –