2011-04-03 53 views
16

我得到了下面的實現來獲取變量宏中的參數個數(目前僅限於16個參數)。但是,對於VS2010,無論傳遞多少個參數,輸出始終爲1With GCC,輸出是正確的,使我得出結論,我必須錯過某些特定的MSVC(10)。爲什麼此可變參數計數宏在VC++中失敗?

#define PP_NARGS(...) \ 
    _xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) 

#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) N 

int main(){ 
    int i = PP_NARGS(A,V,C,X,Y,Z); 

    std::cout << i; 

    std::cin.get(); 
    return 0; 
} 

所以,問題是作爲標題狀態,任何幫助將不勝感激。

回答

23

以下解決方法是否有幫助?

#define EXPAND(x) x 
#define PP_NARGS(...) \ 
    EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) 

我覺得宏是沒有錯的,特別的,但 MSVC的__VA_ARGS__擴張似乎從C99表現不同。

+0

Omg,它*做*工作!真棒!你有解釋爲什麼? – Xeo 2011-04-03 17:30:39

+1

我很高興我可以幫助:-) 老實說,我無法解釋爲什麼(Doh)。 正如我在答案中寫的,我認爲你的宏在C99標準中是很好的。 我把'EXPAND'的東西解釋爲一個純粹的解決辦法,並且可能在那裏沒有任何技術上有趣的事情...... 根據 [這裏](http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement), 這看起來像是VC的錯誤行爲。 – 2011-04-03 18:36:41

+0

非常感謝您採取這種解決方法。按照VS14 CTP3中的描述工作(2008年,MS發現一個錯誤(參見Ise的鏈接),仍然存在)。 – 2014-09-15 12:16:25

-9

__VA_ARGS__是一個C99語言功能。
VC++不是C99編譯器。
做數學。

這就像試圖用Scheme編譯器編譯Pascal並發現它奇怪,它不適用於'begin/end'對。

我不知道C++和Visual Studio如何在所有這些行爲。

+0

雖然[MSDN](http://msdn.microsoft.com/en-us/ library/ms177415%28v = VS.100%29.aspx)似乎不同意你和他們的措辭,我相信我應該可以使用'__VA_ARGS__'。 – Xeo 2011-04-03 15:56:56

+0

您鏈接到的頁面中的示例看起來是C++(或更奇怪的「C/C++」)。我的意思是我的答案只反映C. – pmg 2011-04-03 16:04:39

+0

我相信[此msdn頁面](http://msdn.microsoft.com/en-us/library/teas0593.aspx)是Visual Studio中C宏的參考。 – pmg 2011-04-03 16:18:00

1

問題似乎是Visual Studio擴展__VA_ARGS__之後將它傳遞到後續宏,而gcc在傳遞之前展開它。

在你的情況下,PP_NARGS(A,V,C,X,Y,Z)綁定A,V,C,X,Y,Z__VA_ARGS__,然後將它作爲一個整體傳遞給_xPP_NARGS_IMPL

作爲測試,運行:

#define PP_NARGS(...) \ 
    _xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0) 

#define _xPP_NARGS_IMPL(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,x11,x12,x13,x14,x15,N,...) \ 
    (std::cout << #x1 << std::endl, N) 

int main() { 
    int i = PP_NARGS(A, V, C, X, Y, Z); 
    std::cout << i; 
    return 0; 
} 

你會看到A, V, C, X, Y, Z印在屏幕上,而不是僅僅爲A,你可能會想到。


一種可能的解決方案,通過伊勢紫藤已經所建議的,是通過迫使膨脹:

#define EXPAND(x) x 
#define PP_NARGS(...) \ 
    EXPAND(_xPP_NARGS_IMPL(__VA_ARGS__,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0)) 
相關問題