UFO ET IT

최신 C 및 C ++에서 f (void)가 더 이상 사용되지 않습니다.

ufoet 2020. 11. 10. 22:40
반응형

최신 C 및 C ++에서 f (void)가 더 이상 사용되지 않습니다.


현재 C ++ 프로젝트에서 사용되는 일부 오래된 C 코드를 리팩토링 / 정리 중이며 다음과 같은 기능을 정기적으로 확인합니다.

int f(void)

나는 다음과 같이 쓰는 경향이 있습니다.

int f()

일관성을 향상시키기 위해 코드베이스 전체에서 (void)를 ()로 대체하지 않는 이유가 있습니까? 아니면 내가 알지 못하는 둘 사이에 미묘한 차이가 있습니까? 보다 구체적으로, C ++의 가상 멤버 함수가 다음과 같이 설명되는 경우 :

virtual int f(void)

파생 클래스에는 멤버 함수가 포함됩니다.

int f()

유효한 재정의입니까? 또한 거의 동일한 서명을 기반으로하는 링커 문제가 발생할 가능성이 있습니까?


C에서 선언 int f(void)은 매개 변수가없는 int를 반환하는 함수를 의미합니다. 선언 int f()은 여러 매개 변수를 취하는 int를 반환하는 함수를 의미합니다. 따라서 C에서 매개 변수를받지 않는 함수가있는 경우 전자가 올바른 프로토 타입입니다.

C ++에서는 int f(void)더 이상 사용되지 않으며 int f()특히 매개 변수가없는 함수를 의미하므로 선호됩니다.


Chris의 대답에 덧붙여서, int f()내 경험상 C에서 사용하는 것은 좋지 않습니다. 컴파일러가 함수 선언을 정의와 비교하여 올바르게 호출되는지 확인하는 기능을 잃기 때문입니다.

예를 들어 다음 코드는 표준을 준수하는 C입니다.

#include <stdio.h>
void foo();
void bar(void) {
    foo();
}
void foo(int a) {
    printf("%d\n", a);
}

그러나에 a전달되지 않았기 때문에 정의되지 않은 동작 이 발생합니다 foo.

C ++에는 두 가지 버전이 있습니다 foo. 하나는 인수가없고 다른 하나는 int. 따라서 bar정의되지 않은 버전을 호출하면 링커 오류가 발생합니다 ( foo어디에나 다른 정의가 없다고 가정 ).


위의 답변은 매우 정확하지만 David Tribble의 우수한 페이지에 연결되어 이것과 다른 많은 문제에 대한 훌륭한 설명제공 합니다.

하이라이트 :

C는 빈 매개 변수 목록으로 선언 된 함수와 void로만 구성된 매개 변수 목록으로 선언 된 함수를 구분합니다. 전자는 지정되지 않은 수의 인수를 사용하는 프로토 타입이없는 함수이고 후자는 인수가없는 프로토 타입 함수입니다.

반면에 C ++는 두 선언을 구분하지 않으며 둘 다 인수가없는 함수를 의미하는 것으로 간주합니다.

C 또는 C ++로 컴파일되도록 의도 된 코드의 경우이 문제에 대한 최상의 솔루션은 항상 명시 적 void 프로토 타입으로 매개 변수를 사용하지 않는 함수를 선언하는 것입니다.

빈 함수 프로토 타입은 C99에서 더 이상 사용되지 않는 기능입니다 (C89에서와 같이).

편집 : 표준을 살펴본 후 func (void) 구문이 C ++에서 더 이상 사용 되지 않는 것은 아니지만 일반적으로 C 스타일 관용구로 간주 된다는 점에 주목할 가치가 있습니다. 필자가 만난 대부분의 C ++ 프로그래머는 빈 매개 변수 목록을 선호한다고 생각합니다.

편집 2 : C ++ 표준, 섹션 8.3.5, 단락 2에서 인용 추가하기 :

"parameter-declaration-clause가 비어 있으면 함수는 인수를 갖지 않습니다. 매개 변수 목록 (void)은 빈 매개 변수 목록과 동일합니다.이 특별한 경우를 제외하고 void는 매개 변수 유형이 아닙니다 (void에서 파생 된 유형이지만 , 예 : void *, can). "

두 양식 모두 사용되지 않는다는 언급은 없습니다. 표준의 올바른 섹션을 알려준 Mr. Tribble의 훌륭한 웹 사이트에 다시 한 번 감사드립니다.


tl; dr : void.

C ++의 이전 버전과의 호환성과 아래에서 확인 된 약간의 모호함을 감안할 때 결정적인 답변을 위해 KnR 및 ANSI C로 돌아 가야한다고 주장합니다.

int getline(void);
int copy(void)

Since the specialized versions of getline and copy have no arguments, logic would suggest that their prototypes at the beginning of the file should be getline() and copy(). But for compatibility with older C programs the standard takes an empty list as an old-style declaration, and turns off all argument list checking; the word void must be used for an explicitly empty list. [Kernighan & Richie, the C programming language, 1988, Pgs 32-33]

and..

The special meaning of the empty argument list is intended to permit older C programs to compile with new compilers. But it's a bad idea to use it with new programs. If the function takes arguments, declare them; if it takes no arguments, use void [ibid, Pg. 73]

EDIT: Broke the rest into a separate discussion here: Does specifying the use of void in the declaration of a function that takes no arguments address The Most Vexing Parse?


C11 N1570 standard draft

void f() is deprecated, void f(void) recommended:

6.11.6 Function declarators:

1 The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.

Introduction:

2 Certain features are obsolescent, which means that they may be considered for withdrawal in future revisions of this International Standard. They are retained because of their widespread use, but their use in new implementations (for implementation features) or new programs (for language [6.11] or library features [7.31]) is discouraged.

Detailed discussion: https://stackoverflow.com/a/36292431/895245

C++11 N3337 standard draft

Neither void f(void) nor void f() are deprecated.

void f(void) exists for compatibility with C. Annex C "Compatibility" C.1.7 Clause 8: declarators:

8.3.5 Change: In C ++ , a function declared with an empty parameter list takes no arguments. In C, an empty parameter list means that the number and type of the function arguments are unknown.

Since void f() is deprecated in C and void f(void) recommended, void f(void) will exist for as long as C++ wants to maintain compatibility.

void f(void) and void f() are the same in C++. So the longer void f(void) only makes sense if you care about writing code that compiles under both C and C++, which is likely not worth it.

Detailed discussion: https://stackoverflow.com/a/36835303/895245


In C++, int f(void) is indeed a deprecated declaration which is 100% equivalent to int f(). It is the same signature. The void in this context is as significant as e.g. whitespace. That also means that they are subject to the One Definition Rule (they don't overload) and Derived::f(void) overrides Base::f().

Don't mess with stuff like f(const void), though. There's not a lot of consensus what that kind of weirdness means.

참고URL : https://stackoverflow.com/questions/416345/is-fvoid-deprecated-in-modern-c-and-c

반응형