programing

C void 인수 "void foo(void)"를 사용하는 것이 좋습니까, 아니면 "void foo()"를 사용하지 않는 것이 좋습니까?

newsource 2022. 8. 21. 19:44

C void 인수 "void foo(void)"를 사용하는 것이 좋습니까, 아니면 "void foo()"를 사용하지 않는 것이 좋습니까?

것이 더 좋은가:void foo() ★★★★★★★★★★★★★★★★★」void foo(void)보이드가 있으면 보기 흉하고 일관성이 없어 보이지만 좋다고 들었습니다.★★★★★★★★★★★★★★★★★★?

것이 있는 것도 는, 과 같습니다.void foo()윌?foo(bar);받들????

void foo(void);

이는 C에서 "파라미터 없음"을 나타내는 올바른 방법이며, C++에서도 작동합니다.

단,

void foo();

C++는 C++는 C++는 C++는 C++는 C++는 C!에서는 「알 수 없는 타입의 의 파라미터를 취할 수 를 의미하고, C++에서는 「알 수 없는 타입의 파라메타를 수 있다」를 하고, C++에서는 「알 수 없는 타입의 파라메타」를하고 있습니다.foo(void).

변수 인수 목록 함수는 본질적으로 유형화되어 있지 않으므로 가능하면 피해야 합니다.

C99 견적

이 답변은 C99 N1256 표준 초안의 관련 부분을 인용하고 설명하는 것을 목적으로 한다.

선언자의 정의

선언자라는 말이 많이 나오니까 이해하자.

언어 문법을 통해 다음 밑줄 문자는 선언자임을 알 수 있습니다.

int f(int x, int y);
    ^^^^^^^^^^^^^^^

int f(int x, int y) { return x + y; }
    ^^^^^^^^^^^^^^^

int f();
    ^^^

int f(x, y) int x; int y; { return x + y; }
    ^^^^^^^

선언자는 함수 선언과 정의의 일부입니다.

선언자에는 두 가지 유형이 있습니다.

  • 파라미터 유형 리스트
  • 식별자 리스트

파라미터 유형 리스트

선언은 다음과 같습니다.

int f(int x, int y);

정의는 다음과 같습니다.

int f(int x, int y) { return x + y; }

각 파라미터의 타입을 지정해야 하기 때문에 파라미터 타입 리스트라고 불립니다.

식별자 리스트

정의는 다음과 같습니다.

int f(x, y)
    int x;
    int y;
{ return x + y; }

선언은 다음과 같습니다.

int g();

식별자 목록이 비어 있지 않은 함수는 선언할 수 없습니다.

int g(x, y);

6.7.5.3 "기능 선언자(시제품 포함)"에는 다음과 같은 내용이 포함되어 있습니다.

3 함수 정의의 일부가 아닌 함수 선언자의 식별자 목록은 비어 있어야 한다.

목록이라고 은 식별자만 입니다.x ★★★★★★★★★★★★★★★★★」yf(x, y) , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

이것은 오래된 방법이기 때문에 더 이상 사용할 수 없습니다.6.11.6 함수 선언자는 다음과 같습니다.

1 (시제품 형식의 파라미터 유형 선언자가 아닌) 빈 괄호를 가진 함수 선언자의 사용은 사춘기적 특징입니다.

도입부에서는 사춘기의 특징에 대해 설명합니다.

일부 특징은 미숙하며, 이는 이 국제 표준의 향후 개정에서 그러한 특징이 철회될 수 있음을 의미한다.이러한 기능은 널리 사용되기 때문에 유지되지만 새로운 구현(실장 기능용) 또는 새로운 프로그램(언어용 [6.11] 또는 라이브러리 기능용 [7.26])에서의 사용은 권장되지 않습니다.

선언의 f() vs f(f(disclos)

글을 쓸 때:

void f();

6.7.5 "Declarators"는 문법을 다음과 같이 정의하기 때문에 반드시 식별자 목록 선언이다.

direct-declarator:
    [...]
    direct-declarator ( parameter-type-list )
    direct-declarator ( identifier-list_opt )

수 있습니다.이는 옵션(identifier-list "는 "dentifier-list "는 "로 되어 있습니다.이는 옵션이기 때문입니다( )._opt를 참조해 주세요.

direct-declarator는 괄호를 정의하는 입니다.(...)선언자의 일부입니다.

그렇다면 매개 변수 없이 더 나은 매개 변수 유형 목록을 어떻게 명확히 하고 사용할 수 있을까요? 6.7.5.3 기능 선언자(시제품 포함)는 다음과 같이 말합니다.

10 목록의 유일한 항목으로서 void 유형의 이름 없는 매개변수의 특별한 경우 함수에 매개변수가 없음을 명시합니다.

그래서:

void f(void);

길이에요.

입니다. 우리는 ''을 할 수 입니다.void인수를 다른 방법으로 입력합니다.

void f(void v);
void f(int i, void);
void f(void, int);

f() 선언을 사용하면 어떻게 됩니까?

코드가 잘 컴파일될 수 있습니다. 6.7.5.3 기능 선언자(시제품 포함):

14 함수 정의의 일부가 아닌 함수 선언자의 빈 목록은 파라미터의 수 또는 유형에 대한 정보를 제공하지 않도록 지정합니다.

다음과 같은 이점을 얻을 수 있습니다.

void f();
void f(int x) {}

또, UB가 슬금슬금 올라오는 경우도 있습니다(그리고 운이 좋으면 컴파일러가 알려 줍니다).그 이유를 알아내는 데 어려움을 겪을 것입니다.

void f();
void f(float x) {}

참조: 빈 선언이 int 인수를 가진 정의에서는 기능하지만 float 인수에서는 기능하지 않는 이유는 무엇입니까?

정의의 경우 f() 및 f(표준)

f() {}

f(void) {}

비슷하지만 동일하지는 않습니다.

6.7.5.3 기능 선언자(시제품 포함)는 다음과 같이 말한다.

14 함수 정의의 일부인 함수 선언자의 빈 목록은 함수에 파라미터가 없음을 나타냅니다.

문장은 '이 문장이랑 요.f(void).

그래도...다음과 같이 보입니다.

int f() { return 0; }
int main(void) { f(1); }

는 정의되지 않은 동작에 준거하고 있습니다.단, 다음과 같습니다.

int f(void) { return 0; }
int main(void) { f(1); }

는 다음에서 설명한 바와 같이 적합하지 않습니다.gcc는 인수 없이 정의된 함수에 인수를 전달할 수 있도록 하는 이유는 무엇입니까?

TODO는 그 이유를 정확히 알고 있습니다.시제품이냐 아니냐와 관련이 있어프로토타입을 정의합니다.

C에서 파라미터를 지정하는 방법은 두 가지가 있습니다.하나는 식별자 목록을 사용하고 다른 하나는 파라미터 유형 목록을 사용합니다.식별자 목록은 생략할 수 있지만 유형 목록은 생략할 수 없습니다.따라서 함수 정의에서 인수를 사용하지 않는 함수는 ( 생략된) 식별자 목록을 사용하여 이 작업을 수행합니다.

void f() {
    /* do something ... */
}

파라미터 유형 리스트는 다음과 같습니다.

void f(void) {
    /* do something ... */
}

파라미터 타입 리스트에서 파라미터 타입이 1개만 void인 경우(이 경우 이름이 없어야 합니다), 이는 함수가 인수를 받지 않음을 의미합니다.그러나 함수를 정의하는 두 가지 방법은 선언하는 내용과 다릅니다.

식별자 리스트

첫 번째 정의에서는 함수가 특정 수의 인수를 사용하지만 식별자 목록을 사용하는 모든 함수 선언과 마찬가지로 카운트는 전달되지 않으며 필요한 유형의 인수를 사용하지 않습니다.따라서 발신자는 사전에 종류와 개수를 정확히 알아야 합니다.따라서 발신자가 함수를 호출하여 인수를 지정하면 동작은 정의되지 않습니다.예를 들어, 스택이 파손될 가능성이 있습니다.이것은, 착신측 함수가 제어를 취득했을 때에 다른 레이아웃이 필요하기 때문입니다.

함수 파라미터에서 식별자 리스트를 사용하는 것은 권장되지 않습니다.옛날에는 사용되었고 지금도 많은 생산 코드에 있습니다.이러한 인수 프로모션에 의해 중대한 위험이 발생할 수 있습니다(승격된 인수 유형이 함수 정의의 파라미터 유형과 일치하지 않으면 동작도 정의되지 않습니다). 물론 훨씬 안전성이 떨어집니다. 항상 ' 때'를 사용하세요.void파라미터가 없는 함수의 경우, 함수의 정의와 제한 사항 모두 해당됩니다.

파라미터 유형 리스트

가 인수를 0으로 그리스트를 로 이를 이는 "0", "0"으로 불립니다.prototype호출자가 함수를 호출하여 인수를 지정하면 이는 오류이며 컴파일러는 적절한 오류를 출력합니다.

함수를 선언하는 두 번째 방법에는 많은 이점이 있습니다.하나는 물론 파라미터의 양과 종류를 확인하는 것입니다.또 다른 차이점은 컴파일러가 파라미터 유형을 알고 있기 때문에 파라미터 유형에 인수의 암묵적인 변환을 적용할 수 있다는 것입니다.파라미터 유형 리스트가 존재하지 않는 경우 이 작업은 수행할 수 없으며 인수는 승격된 유형(기본 인수 승격이라고 함)으로 변환됩니다. char될 것이다int예를 들어,float될 것이다double

함수에 대한 복합 유형

덧붙여서 파일에 생략된 식별자 리스트와 파라미터 타입 리스트가 모두 포함되어 있으면 파라미터 타입 리스트는 wins가 됩니다.끝에 있는 기능 유형에는 다음과 같은 프로토타입이 포함됩니다.

void f();
void f(int a) {
    printf("%d", a);
}

// f has now a prototype. 

두 선언 모두 모순되는 것은 없기 때문이다.그러나 두 번째는 추가로 할 말이 있었다.즉, 하나의 주장이 받아들여진다는 것입니다.같은 것을 반대로 할 수 있다.

void f(a) 
  int a;
{ 
    printf("%d", a);
}

void f(int);

첫 번째는 식별자 목록을 사용하여 함수를 정의하고 두 번째는 파라미터 유형 목록을 포함하는 선언을 사용하여 해당 함수의 프로토타입을 제공합니다.

void foo(void)no parameters allowed parameters allowed 、 :: is is is is:::: ::::::: :::::::라고 명시되어 있기 에 더 .

void foo()(컴파일러에 따라서는) 파라미터를 송신할 수 있습니다.적어도 이것이 함수의 정의가 아닌 선언인 경우입니다.

C++ 에서는, 에 차이가 없습니다.main() ★★★★★★★★★★★★★★★★★」main(void).

하지만 C에서는main()는 임의의 수의 파라미터를 사용하여 호출됩니다.

예:

main (){
    main(10, "abc", 12.28);
    // Works fine!
    // It won't give the error. The code will compile successfully.
    // (May cause a segmentation fault when run)
}

main(void)파라미터 없이 호출됩니다.패스하려고 하면 컴파일러 오류가 발생합니다.

예:

main (void) {
     main(10, "abc", 12.13);
     // This throws "error: too many arguments to function ‘main’ "
}

외에도 많은 합니다.void function(void) 이유: pracitic한 이유

그 , 하면 됩니다.function(void)이치노

[ ]를 voidfunction()따라서 모든 함수 호출도 검색되므로 실제 구현은 더 어려워집니다.

언급URL : https://stackoverflow.com/questions/693788/is-it-better-to-use-c-void-arguments-void-foovoid-or-not-void-foo