2011-03-09 53 views
3

代碼:宏的實際參數太多?

#include <iostream> 

using namespace std; 

#define ADD(x,y) ((x)+(y)) 

int main(int argc, char** argv) 
{ 
    cout << ADD(1,2,) << endl; 
    return 0; 
} 

編譯器輸出:

1>Compiling...
1>main.cpp
1>c:\warn_test\main.cpp(9) : warning C4002: too many actual parameters for macro 'ADD'

爲什麼沒有這樣的錯誤?

g++ (GCC) 4.2.1 20070719 [FreeBSD]給出更合理的(在我心中)輸出:

main.cpp:9:18: error: macro "ADD" passed 3 arguments, but takes just 2
main.cpp: In function 'int main(int, char**)':
main.cpp:9: error: 'ADD' was not declared in this scope

雖然我不能完全確定什麼或者編譯器認爲第三個參數是。

編輯:添加完整的gcc輸出和版本信息。

+2

我懷疑沒有很好的理由,MSDN頁面http://msdn.microsoft.com/en-us/library/y37zb304表明它根據編譯器版本而變化,無論它是警告還是錯誤。也許是爲了支持某些依賴於它的只是一個警告的可惡的遺留代碼。第三個參數是一個0長度的令牌序列,如果有第三個宏參數,可以將其替換爲宏擴展。請注意,標準允許實現編譯具有任何特定於實現的含義的代碼,只要它們發佈診斷,所以它是「古怪」而不是「錯誤」。 – 2011-03-09 16:20:06

+0

什麼是錯誤或警告是可配置的。您的抱怨是否說不同的編譯器有不同的默認值?這將很容易解決你的項目設置! – 2011-03-09 17:08:16

回答

0

您使用ADD(1,2,),注意第二個,。刪除它,它會編譯得很好!

@schnaader:你說得對,我讀得太快了。抱歉。

請提供有關編譯器的更多詳細信息。我用:G ++(Ubuntu的/ Linaro的4.4.4-14ubuntu5)4.4.5,這是結果我得到:

test.cpp:9: error: macro "ADD" passed 3 arguments, but takes just 2 
test.cpp: In function ‘int main(int, char**)’: 
test.cpp:9: error: ‘ADD’ was not declared in this scope 

[EDIT2] 不好意思,又有點太快:-)。我看到你用visual studio標記了它。 VS比g ++更寬容。我想 - 因爲在這種情況下很容易解決 - 它會自動糾正它。

+2

這不是他的問題,他知道,因爲他預計它會拋出一個錯誤... – schnaader 2011-03-09 16:14:52

+0

@schnaader:沒錯。警告行爲讓我感到非常反直覺。我想知道是否有C++規範的某些方面可以讓Microsoft在這種情況下不會出錯。 – genpfault 2011-03-09 16:17:56

+0

用完整的'gcc'版本和輸出編輯我的問題。 – genpfault 2011-03-09 16:23:46

1

我想這是有點編譯器的選擇。如果有第三個參數,它可能會更成問題,但如果沒有,您可以爭論只是忽略逗號或拋出錯誤。微軟似乎經常容忍更多的錯誤(如在IE瀏覽器HTML解析中)。

2

我打算拋出一個完整的猜測,受Steve Jessop的評論的啓發,它與可變宏支持有關。

當Visual Studio團隊實現可變宏時,可能會更容易使它成爲警告。我注意到實現類似代碼時的不同級別的容差:

#define MACRO(...) my_func(true, __VA_ARGS__); 

MACRO(1,,2); // Missing argument 
MACRO(1,); // missing tail 
MACRO(); // no arguments 

某些編譯器錯誤,警告或忽略各種情況。我不知道標準所說的是什麼。