2012-01-08 5 views
31

C++에서는 일부 상황에서 매개 변수의 이름을 생략하는 경향이 있습니다. 그러나 C에서 매개 변수의 이름을 생략하면 오류가 발생합니다.매개 변수 이름 생략, C++ 대 C

void foo(int); //forward-decl, it's OK to omit the parameter's name, in both C++ and C 

int main() 
{ 
    foo(0); 
    return 0; 
} 

void foo(int) //definition in C, it cannot compile with gcc 
{ 
    printf("in foo\n"); 
} 

void foo(int) //definition in C++, it can compile with g++ 
{ 
    cout << "in foo" << endl; 
} 

이유입니다 : 여기

코드인가? C 함수 정의에서 매개 변수의 이름을 생략 할 수 있습니까?

+2

멀티 - 언어 소스 파일 작성 (매우) 힘든 일입니다. 각 단일 소스 파일을 하나의 언어로만 유지하는 것이 좋습니다. – pmg

+0

@pmg, 귀하의 조언에 감사드립니다.) – Alcott

+0

C와 C++ 모두에서 컴파일 할 것이 있으면'printf'와'str :: cout'을 사용하는 별도의 함수를 작성할 필요가 없습니다. 'printf'는 두 언어 모두에서 작동합니다. 나는 그 기능이 동일하지 않을 수도 있기 때문에, 하나로서 쓰여질 수있는 두 가지 기능을 사용하는 것에 반대한다. –

답변

33

아니요, C에서는 함수 정의에서 매개 변수의 식별자를 생략 할 수 없습니다.

C99 표준 말한다

[6.9.1.5]를 선언자는 파라미터 타입리스트를 포함하는 경우, 각 변수의 선언 파라미터리스트의 특별한 경우를 제외하는 식별자를 포함한다 유형이 void 인 단일 매개 변수 으로 구성되며이 경우 식별자가 없어야합니다. No 선언 목록을 따라야합니다.

는 C++ 14 표준 메시지 :

[8.3.5.11] 식별자 임의로 파라미터 이름으로 제공 될 수있다; 함수 정의에 있으면 매개 변수 ("공식 인수"라고도 함)의 이름을 지정합니다. [참고 : 특히, 파라미터 이름과 같은 함수에 선택적 다른 선언에서 파라미터 함수의 정의에 사용되는 이름 데피니션 가 동일 할 필요는 없다.]

+0

그래서 변수 이름을 식별자라고 부릅니까? –

+5

@ Mr.TAMER : 모든 변수 이름은 식별자이지만 일부 식별자는 변수 이름이 아닙니다. –

+0

@DietrichEpp : 알겠습니다, 감사합니다. :) 빠른 검색으로 [this] (http://msdn.microsoft.com/en-us/library/565w213d.aspx)를 발견했습니다. –

4

함수 프로토 타입에서 매개 변수 이름을 생략 할 수 있지만 함수 구현에서 선언해야합니다. 예를 들어,이 컴파일 및 GCC 4.6.1

void foo(int, int); 

void foo(int value, int secondValue) 
{ 
    printf("In foo with value %d and %d!\n", value, secondValue); 
} 

int main(int argc, char **argv) 
{ 
    foo(10, 15); 
    return 0; 
} 

출력에서 ​​잘 실행 : In foo with value 10 and 15!에 관해서는

왜 (다른 기준 때문에보다가 그렇게 말) : C++은 사용하지 않고 함수를 호출 할 수 있습니다 모든 논증, C는 그렇지 않다. C에서 함수에 대한 모든 인수를 제공하지 않으면 컴파일러에서 throw합니다. error: too few arguments to function 'foo'

+4

C++ *에서는 해당 매개 변수에 기본값이없는 경우 호출에서 인수를 생략 할 수 없습니다. 그리고이 경우, 디폴트 값은 암시 적으로 전달되며 함수는 값을 참조 할 경우 인수의 이름을 제공해야합니다. 차이점은 C++에서 함수가 매개 변수 중 하나를 무시하는 것이 더 많은 경우가 있다는 것입니다. –

15

이유가있다 그것이 각 언어 표준이 말하는 것입니다. 그러나 차이점에 대한 근거가 있습니다.

매개 변수의 이름을 지정하지 않으면 해당 매개 변수를 참조 할 수 없습니다.

C에서 함수가 매개 변수 중 하나를 무시하면 선언 및 정의에서 함수를 제거하고 호출에서 전달하지 않는 것이 일반적입니다. 예외는 콜백 함수 일 수 있습니다. 콜렉션 함수는 모두 같은 유형이어야하지만 모든 함수가 반드시 매개 변수를 사용하는 것은 아닙니다. 그러나 이것은 매우 일반적인 시나리오는 아닙니다.

C++에서 함수가 부모 클래스에 정의 된 함수에서 파생 된 경우 하위 함수가 매개 변수 값 중 하나를 사용하지 않아도 부모 함수와 동일한 서명을 가져야합니다.

(기본 매개 변수와 관련이 없으므로 C++의 매개 변수에 기본값이있는 경우 호출자는 명시 적으로 매개 변수를 전달할 필요는 없지만 함수 정의는 계속하려면 이름을 제공해야합니다. 그것을 참조하십시오.)

5

순전히 실용적인 수준에서, 나는 매일 이것을 처리합니다. 현재까지 가장 좋은 해결책은 전 처리기를 사용하는 것입니다. 내 공통 헤더 파일이 포함되어 사용하지 않은 사용의

//------------------------------------------------------------------------- 
// Suppress nuisance compiler warnings. Yes, each compiler can already 
// do this, each differently! VC9 has its UNREFERENCED_PARAMETER(), 
// which is almost the same as the SUPPRESS_UNUSED_WARNING() below. 
// 
// We append _UNUSED to the variable name, because the dumb gcc compiler 
// doesn't bother to tell you if you erroneously _use_ something flagged 
// with __attribute__((unused)). So we are forced to *mangle* the name. 
//------------------------------------------------------------------------- 
#if defined(__cplusplus) 
#define UNUSED(x)  // = nothing 
#elif defined(__GNUC__) 
#define UNUSED(x)  x##_UNUSED __attribute__((unused)) 
#else 
#define UNUSED(x)  x##_UNUSED 
#endif 

예는 다음과 같습니다

void foo(int UNUSED(bar)) {} 

때때로 당신이 실제로 어설 션() 또는 디버그 문에, 예를 들어, 매개 변수를 참조 할 필요가있다. 당신이 할 수 있도록를 통해 : 또한

#define USED_UNUSED(x) x##_UNUSED // for assert(), debug, etc 

, 다음은 유용합니다

#define UNUSED_FUNCTION(x) inline static x##_UNUSED // "inline" for GCC warning 
#define SUPPRESS_UNUSED_WARNING(x) (void)(x) // cf. MSVC UNREFERENCED_PARAMETER 

예 :

UNUSED_FUNCTION(int myFunction)(int myArg) { ...etc... } 

과 :

void foo(int bar) { 
#ifdef XXX 
    // ... (some code using bar) 
#else 
    SUPPRESS_UNUSED_WARNING(bar); 
#endif 
} 
+1

이것은 이틀 늦었습니다. 나는 그것을 사용하지 않을 것이기를 바란다. –