programing

C89, C90 또는 C99의 모든 기능에 시제품이 필요합니까?

prostudy 2022. 6. 17. 21:36
반응형

C89, C90 또는 C99의 모든 기능에 시제품이 필요합니까?

C의 모든 기능(메인 기능 제외)은 동일한 번역 유닛에서 정의된 후에만 사용되는 경우에도 시제품을 사용해야 합니까?

프로토타입은 함수의 파라미터 유형을 지정하는 함수 선언입니다.

1978년 Kernighan & Ritchie의 "The C Programming Language" 초판에 기술된 언어인 Pre-ANSI C는 프로토타입을 가지고 있지 않았다.함수 선언에서는 파라미터의 수나 유형을 기술할 수 없었다.올바른 인수의 수와 타입을 전달하는 것은 발신자에게 달려 있습니다.

ANSI C는 파라미터의 유형을 지정하는 선언인 "프로토타입"을 도입했습니다(초기 C++에서 빌린 기능).

C89/C90(ANSI 규격과 ISO 규격은 같은 언어를 나타냄)에서는, 눈에 보이는 선언 없이 함수를 호출하는 것이 합법입니다.암묵적인 선언이 제공됩니다.암묵적인 선언이 실제 정의와 호환되지 않는 경우(예를 들어 호출)sqrt("foo")동작은 정의되어 있지 않습니다.이 암묵적인 선언도 비프로토타입 선언도 바리에딕 함수와 호환될 수 없기 때문에 바리에딕 함수에 대한 호출은 다음과 같습니다.printf또는scanf)는 가시적인 프로토타입을 가지고 있어야 합니다.

C99가 암묵적인 선언을 폐기했습니다.눈에 보이는 선언이 없는 함수에 대한 호출은 제약 위반이며 컴파일러 진단이 필요합니다.그러나 이 선언은 여전히 프로토타입일 필요는 없습니다.파라미터 유형을 지정하지 않은 오래된 스타일의 선언일 수 있습니다.

C11은 이 영역에서 큰 변화는 없었다.

따라서 2011년 ISO C 표준에서도 구식 함수 선언 및 정의(1989년 이후 "사춘기")는 여전히 적합 코드로 허용됩니다.

1989년으로 거슬러 올라가는 C의 모든 버전에 대해 스타일상 모든 기능에 프로토타입을 사용하지 않을 이유가 거의 없습니다.오래된 형식의 선언과 정의는 오래된 코드가 깨지지 않도록 하기 위해서만 유지됩니다.

그것은 당신이 말하는 '완전히 표준에 준거한다'는 것에 달려있다.단, "사용하기 전에 모든 기능에 시제품이 적용 범위 내에 있는지 확인하는 것이 좋습니다."라는 짧은 답변입니다.

보다 정규화된 답변은 함수가 변수 인수를 받아들일 경우(특히printf()기능 제품군)을 엄격하게 준수하려면 프로토타입이 적용 범위에 있어야 합니다.이것은, C89(ANSI로부터) 및 C90(ISO로부터.섹션 번호를 제외하고 C89와 동일)에 해당됩니다.단, 'varargs' 함수 이외의 함수는 varargs를 반환한다.int선언할 필요가 없으며, 다른 것을 반환하는 함수int반환 유형을 나타내는 선언이 필요하지만 인수 목록의 프로토타입은 필요하지 않습니다.

단, 시제품이 없을 때 함수가 '정상적인 프로모션'의 대상이 되는 인수를 취하는 경우(예:char또는short- 둘 다 로 변환됩니다.int더 심각한 것은, 아마도, 더 심각한 것은, 이 함수가float대신double시제품이 필요합니다.표준 준거 컴파일러 하에서 오래된 C 코드를 컴파일할 수 있도록 규격이 느슨했습니다. 오래된 코드는 사용 전에 함수가 선언되는 것을 우려하기 위해 작성되지 않았습니다.또한 정의에 따르면 오래된 코드는 표준이 있을 때까지 C에서 사용할 수 없었기 때문에 프로토타입을 사용하지 않았습니다.

C99는 '암묵적 침입'을 허용하지 않습니다...그 말은 '같은 이상한 경우 둘 다'static a;' (an.int디폴트) 및 암묵적인 함수 선언도 있습니다.이는 ISO/IEC 9899:1999의 서문에 기재되어 있으며(기타 50여 가지 주요 변경사항과 함께), 이 표준을 이전 버전과 비교하고 있습니다.

  • 암묵적으로 제거하다int
  • 암묵적 함수 선언 제거

ISO/IEC 9899:1990에서 §6.3.2.2 함수 호출은 다음과 같이 기술되어 있습니다.

함수 콜에서 괄호 안의 인수 목록 앞에 있는 식이 식별자로만 구성되어 있고 이 식별자에 대해 선언이 표시되지 않으면 해당 식별자는 함수 콜을 포함하는 가장 안쪽 블록에서 선언과 동일하게 암묵적으로 선언됩니다.

extern int identifier();

나타났다.38

38 즉, 블록 스코프를 가진 식별자가 파라미터 정보 없이 타입 함수와의 외부 링크를 선언하고, 이 ID를 반환한다.int실제로 타입 '함수 리턴'으로 정의되어 있지 않은 경우int동작은 정의되어 있지 않습니다.

이 단락은 1999년 기준에서 누락되었다.나는 (아직) 그 용어의 변화를 추적하지 않았다.static a;C90에서 허가하지 않음(필요)static int a;)을 클릭합니다.

함수가 스태틱한 경우 해당 함수는 사용하기 전에 정의될 수 있으므로 선언 앞에 사용할 필요가 없습니다.비정적 함수가 그 앞에 선언을 하지 않고 정의되어 있는 경우, GCC를 위터로 설득할 수 있습니다(-Wmissing-prototypes).

새로운 함수를 쓸 때 좋은 팁은 함수의 args나 반환 타입에 대한 생각이 바뀌었을 때 프로토타입도 수정할 필요가 없도록 main을 맨 아래에 거꾸로 적는 것입니다.프로토타입을 지속적으로 수정하고, 최신이 아닐 때 컴파일러의 모든 경고를 처리하는 것은 매우 지루합니다.

기능이 함께 원활하게 작동되면 코드를 잘 명명된 모듈로 이동하고 프로토타입을 같은 이름의 .h 파일에 넣습니다.그것은 심각한 시간을 절약한다.5년 만에 찾은 가장 큰 생산성 지원입니다.

아니요, 기능에 항상 시제품이 필요한 것은 아닙니다.유일한 요건은 함수를 사용하기 전에 "선언"해야 한다는 것입니다.함수를 선언하는 방법에는 프로토타입을 작성하는 방법과 함수 자체를 작성하는 방법이 있습니다.정의는 항상 선언이지만 모든 선언이 정의인 것은 아닙니다.

내가 아는 한 (ANSI C89/ISO C90에서는) 아니요.C99에 대해서는 잘 모르겠습니다만, 같은 것을 기대하고 있습니다.

개인 메모:기능 프로토타입은...

  1. (A()가 B()를 호출하고 B()가 A()를 호출하는 경우) 또는
  2. 기능을 내보내고 있습니다.그렇지 않으면 불필요한 느낌이 듭니다.

예, 모든 함수는 프로토타입을 가지고 있어야 하지만, 그 프로토타입을 별도의 선언이나 함수 정의의 일부로 표시할 수 있습니다.C89 이상에서 작성된 함수 정의에는 당연히 프로토타입이 있지만, 고전적인 K&R 스타일로 작성하면 다음과 같습니다.

main (argc, argv)

  int argc;
  char **argv;

{
  ...
}

그러면 함수 정의에는 프로토타입이 없습니다.ANSI C(C89) 스타일을 쓰는 경우는, 다음과 같습니다.

main (int argc, char **argv) { ... }

함수 정의에는 프로토타입이 있습니다.

언급URL : https://stackoverflow.com/questions/434763/are-prototypes-required-for-all-functions-in-c89-c90-or-c99

반응형