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 인 토큰 시퀀스이며 세 번째 매크로 인수가있는 경우 매크로 확장으로 대체 될 수 있습니다. 표준에서는, 실장이, 진단을 발행하면 (자), 구현 고유의 의미를 가지는 무효 인 코드를 컴파일 할 수 있도록 (듯이)하고 있습니다. 따라서, 「잘못했다」가 아닌 「기발한」것이됩니다. –

+0

오류 또는 경고를 구성 할 수있는 대상은 무엇입니까? 다른 컴파일러가 다른 기본값을 가지고 있다는 불만이 있습니까? 프로젝트 설정에서 쉽게 수정할 수 있습니다! –

답변

0

ADD(1,2,)을 사용하고 두 번째 숫자는 ,입니다. 그것을 제거하면 잘 컴파일됩니다!

@schnaader : 네 말이 맞아, 너무 빨리 읽었 어. 죄송합니다.

[편집] 해당 컴파일러에 대한 자세한 내용을 제공해주십시오. g ++ (우분투/리나 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] 죄송합니다, 다시 조금 너무 빨리 :-). 나는 당신이 비주얼 스튜디오로 태그를 붙인 것을 본다. VS는 g ++보다 관대합니다. 이 경우에는 쉽게 해결할 수 있기 때문에 자동으로 수정됩니다.

+2

그건 그의 질문이 아니었고, 그는 그가 오류를 던질 것으로 예상했기 때문에 ... – schnaader

+0

@schnaader : 정확합니다. 경고 행동은 극도로 반 직관적 인 것으로 나를 쳤습니다. 이 경우 C++ 스펙에서 Microsoft가 오류를 범하지 않게하는 부분이 있는지 알고 싶었습니다. – genpfault

+0

완전한'gcc' 버전으로 내 질문을 수정하고 출력했습니다. – genpfault

1

나는 이것이 다소 컴파일러의 선택이라고 생각한다. 세 번째 매개 변수가 있다면 더 문제가 될 수 있지만 그렇지 않은 경우에는 쉼표를 무시하거나 오류를 던지는 것에 대해 논쟁 할 수 있습니다. Microsoft는 (IE HTML 구문 분석에서와 같이) 더 많은 오류를 허용하는 경향이 있습니다.

2

가변적 인 매크로 지원과 관련이 있다는 Steve Jessop의 의견에서 영감을 얻은 완전한 추측을 던지려고합니다.

아마도 비주얼 스튜디오 팀이 가변 매크로를 구현할 때 경고를하는 것이 더 쉬울 수도 있습니까? 내가 좋아하는 코드를 구현할 때 관용의 다양한 수준 나타났습니다 :

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

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

어떤 컴파일러 오류, 경고 또는 다양한 상황을 무시합니다. 나는 표준이 tho라고 말하는 것을 모른다.