매개 변수 이름 생략, 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 함수 정의에서 파라미터 이름을 생략할 수는 없습니까?
아니요, C에서는 함수 정의에서 매개 변수에 대한 식별자를 생략할 수 없습니다.
C99 표준은 다음과 같습니다.
[6.9.1.5] 선언자가 매개변수 형식 리스트를 포함하는 경우, 각 매개변수의 선언은 void 형식의 단일 매개변수로 구성된 매개변수 리스트의 특별한 경우를 제외하고 식별자를 포함해야 하며, 이 경우 식별자가 없어야 합니다.선언 목록이 뒤따라서는 안 됩니다.
C++14 표준은 다음과 같습니다.
[8.3.5.11] 식별자는 선택적으로 매개변수 이름으로 제공될 수 있으며, 함수 정의에 존재하는 경우 매개변수 이름을 지정합니다(때로는 "형식 인수"라고 함). [참고: 특히, 매개변수 이름은 함수 정의에서 선택적이며 다른 선언의 매개변수에 사용되는 이름이며 함수의 정의가 같을 필요는 없습니다.]
그 이유는 각 언어 기준에 그렇게 나와 있지만, 그 차이에 대한 근거가 있기 때문입니다.
매개 변수의 이름을 지정하지 않으면 함수가 해당 매개 변수를 참조할 수 없습니다.
C에서 함수가 매개 변수 중 하나를 무시하면 일반적으로 선언과 정의에서 제거하고 호출에 전달하지 않는 것이 의미가 있습니다.콜백 함수는 예외일 수 있습니다. 함수 모음은 모두 동일한 유형이어야 하지만 모든 함수가 매개 변수를 사용할 필요는 없습니다.하지만 그것은 그리 흔한 시나리오는 아닙니다.
C++에서 함수가 일부 부모 클래스에 정의된 함수에서 파생된 경우 자식 함수가 매개 변수 값 중 하나를 사용하지 않더라도 부모와 동일한 서명을 가져야 합니다.
(C++의 매개 변수가 기본값을 가지고 있다면 호출자는 명시적으로 전달할 필요가 없지만 함수 정의가 참조할 경우 이름을 제공해야 합니다.)
업데이트: C 표준의 다음 버전(C23, ISO/IEC 9899:2023(E))에서는 매개 변수 이름을 생략할 수 있습니다.
순수하게 실용적인 차원에서, 저는 이것을 매일 처리합니다.현재까지 가장 좋은 해결책은 전처리기를 사용하는 것입니다.내 공통 헤더 파일에는 다음이 포함됩니다.
//-------------------------------------------------------------------------
// 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
UNSED의 사용 예는 다음과 같습니다.
void foo(int UNUSED(bar)) {}
assert() 또는 debug 문과 같이 실제로 매개 변수를 참조해야 하는 경우가 있습니다.이 작업은 다음을 통해 수행할 수 있습니다.
#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
}
함수 프로토타입에서 매개변수 이름을 생략할 수 있지만 함수 구현에서 선언해야 합니다.예를 들어, 이것은 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의 함수에 모든 인수를 제공하지 않는다면, 컴파일러는 다음을 던질 것입니다.error: too few arguments to function 'foo'
언급URL : https://stackoverflow.com/questions/8776810/parameter-name-omitted-c-vs-c
'it-source' 카테고리의 다른 글
Spring Boot에서 포함된 Tomcat 예외 처리 (0) | 2023.07.15 |
---|---|
JPA Query를 사용하여 데이터를 DB에 삽입하는 방법은 무엇입니까? (0) | 2023.07.15 |
@RestController 메서드는 기본적으로 트랜잭션인 것 같습니다. 왜죠? (0) | 2023.07.10 |
스프링 구성 클래스의 로드 순서를 적용하는 방법은 무엇입니까? (0) | 2023.07.10 |
HTML 태그에 대한 ASP.NET 컨트롤 등가물 (0) | 2023.07.10 |