문제

세션 성적표 :

>type lookma.c
int main() {
  printf("%s", "no stdio.h");
}

>cl lookma.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

lookma.c
Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lookma.exe
lookma.obj

>lookma
no stdio.h
도움이 되었습니까?

해결책

엄격한 규정 준수 모드 (즉, 이론에서 "를 의미 함)에서는 범위에서 함수의 프로토 타입 선언없이 가변 수의 인수를 취하는 함수를 호출 할 때 정의되지 않은 동작을 호출합니다 (나쁜). 즉, 컴파일러가 사용하는 프로그램에서 좋아하는 모든 것을 수행 할 수 있습니다. printf() 프로토 타입없이 #include <stdio.h> 또는 동등한 선언. "좋아하는 것"에는 옵션 중 하나로 올바르게 작동하는 것이 포함됩니다. 그것은 당신의 예에서 선택한 옵션 인 것 같습니다.

실제로, 코드는 공식적인 선언 없이도 대부분의 실용적인 컴파일러에서 잘 작동합니다. printf() 기능.

QRDL에 의해 지적 된 바와 같이, C 컴파일러가 C 라이브러리와 연결되기 때문에 함수는 발견되었다.

C99 및 'Incmilicit Int'에 대한 Chris Young의 의견은 정확하지만 '변수 인수 기능에 대한 규칙은 C89와 C99에 모두 적용됩니다. 대부분의 컴파일러는 그렇게 컴파일하지 않는 코드가 너무 많기 때문에 기본적으로 엄격한 C99 호환 모드에서 작동하지 않습니다.

Chris Young은 다음과 같이 말했습니다.

명확히하기 위해, 내 의견은 C99 암시 적 선언을 제거하는 것입니다. "내부 int"라고 말함으로써, 나는 당신이 foo (void)와 같은 선언을 허용하는 C89 기능을 언급하고 있다고 생각합니다. int foo (void)를 의미하기 위해 C99도 제거했습니다.

크리스는 물론 정확합니다. C99 표준에서 제거 된 두 가지 '암시 적 선언'기능이있었습니다. 표준에 대한 서문은 다음과 같이 나열됩니다.

  • 암시 적 제거 int
  • 암시 적 기능 선언을 제거하십시오

나는 명확하게 생각하지 않았다. 그럼에도 불구하고, C89와 C99는 모두 가변 수의 인수를 취하는 함수의 범위로 프로토 타입을 요구합니다.

설명하려면 :

extern int pqr();
int main(void)
{
    int i = pqr(1, 3);
    return i;
}

첫 번째 줄이 없으면 기능의 암시 적 선언을 가진 올바른 C89 조각입니다. pqr() 정수를 반환하는 함수 (지정되지 않은 인수 포함). 첫 번째 줄이 바뀌면 extern pqr();, 이것은 명시적인 선언이있는 올바른 C89 조각입니다. pqr() 정수를 반환하는 함수 (지정되지 않은 인수 포함)이지만 리턴 유형은 '암시 적입니다. int'. 서면으로, 기능은 명시 적으로 선언되고 명시 적으로 int 반환 유형 - 그러나 여전히 지정되지 않은 인수가 있습니다. 나는 그것이 유효한 C99라고 생각합니다. 확실히, GCC (3.4.4)는 옵션으로 그것을 받아들입니다. '-std=c99 -pedantic". 이상적으로는 기능 선언에 전체 프로토 타입이 포함되어야합니다. pqr() 타원체로 정의되었으며 그 프로토 타입이 필요합니다. 이론에 의하면!)

다른 팁

원래이 C ++에 태그를 지정했지만 C 프로그램 인 것 같습니다. C는 스코프에 프로토 타입이없는 경우 (#include의 누락으로 인한 경우) 함수에 대한 암시 적 선언을 자동으로 제공합니다.u003Cstdio.h> ). 암시 적 선언은 다음과 같습니다.

int printf();

Printf는 int를 반환하고 여러 인수를 할 수있는 함수입니다. 이 프로토 타입은 귀하의 전화를 위해 작동했습니다. 당신은 #include해야합니다u003Cstdio.h>

마지막으로 현재 C 표준 (ISO/IEC 9899 : 1999 또는 구어체로 "C99")이 수행한다고 덧붙여 야합니다. ~ 아니다 암시 적 선언을 허용하면이 프로그램은 준수하지 않습니다. 암시 적 선언이 제거되었습니다. 컴파일러가 C99를 지원하지 않는다고 생각합니다. C ++는 또한 올바른 프로토 타입이 필요하며 암시 적 선언을 수행하지 않습니다.

printf() 표준 C 라이브러리에 위치하고 링커는 항상 표준 라이브러리를 실행 파일에 연결하므로 모든 표준 기능이 발견되며 연결 문제가 없습니다.

C 컴파일러가 프로토 타입 반환없이 해당 기능을 가정하므로 문제를 일으킬 수있는 프로토 타입이 아닌 기능을 사용하는 데 적절한 헤더를 포함시키지 않으면 int 가변적 인 수의 인수를 취합니다. 따라서 항상 헤더를 포함하십시오. 안전 울타리입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top