1
#include<stdio.h> 
int main() 
{ 
    //void foo(); 
    int c= 5; 
    c=foo(); 
    printf("\n%d",c); 
    return 0; 
} 
void foo() 
{ 
    printf("I am foo"); 
} 

내가 프로토 타입 선언을 주석하고 다음 출력을 제공int 변수에 반환 유형 void가있는 함수 호출 반환 값을 할당하면 어떻게됩니까?</p> <blockquote> <p>내가 foo는 프로토 타입으로</p> <p>8</p> </blockquote> <p>가 말하는 오류를 제공 오전 :

공백 값은 무시해야합니다.

내 질문은 프로토 타입 선언이 없을 때 출력으로 나타나는 내부적으로 무엇이 발생 했습니까? 그 이유는 무엇입니까?

저는 TDM-GCC 4.9.2 64 비트 컴파일러가있는 Dev C++ 편집기를 사용하고 있습니다.

+0

UB가됩니다. –

+1

환자 : 의사, 이럴 때 아파요. Doctor : 그만해! 구현과 관련하여 계약을 위반할 때 어떤 일이 발생하는지는 구현이 잘된 일을 잘 수행 할 수 있다는 것입니다. – paxdiablo

답변

3

이것이 성공적으로 작성된 유일한 이유는 암시 적 int 규칙 (현재 C 표준의 최신 개정판에서 제거됨) 때문입니다.

컴파일러에서 앞으로 선언이 표시되지 않습니다. foo이므로 반환 유형이 int라고 가정합니다. 그런 다음 귀하의 void foo()을 작성하고 전화하십시오. 결국 말했듯이 프로그램의 동작은 정의되지 않습니다.

1

Gcc 컴파일러가 경고를 보내고 성공적으로 실행하고 공백이있는 문자를 반환합니다. 그러나 일부 컴파일러는 오류를 나타냅니다.

pp.c:10:6: warning: conflicting types for ‘foo’ [enabled by default] 
void foo() 
    ^
pp.c:6:6: note: previous implicit declaration of ‘foo’ was here 
    c=foo(); 
1

더 프로토 타입 선언

음이없는, 즉,

  • 포인트 1 정교한 C.

    잘못되었습니다 당신은 ~ 할 수 없다. 이전에 선언되지 않은 함수가 호출되었습니다. 이것은 C 표준 규칙에 위배됩니다.

  • 포인트 2 : 즉시 당신은 앞으로 선언을 추가 할 때, 당신은 할당 연산자의 RHS 피연산자가 될 수없는 void 유형으로, 컴파일 오류가됩니다 및이의 제한 위반 할당 연산자.


참고 :

사전 C99, 그것은이 함수가 int를 반환되며 숫자를 수용 할 것으로 가정 하였다 알려진 프로토 타입없이 호출되는 함수를 가질 수 있었다 매개 변수 그러나 이것은 "암시적인 int 규칙"이 표준에서 제거됨에 따라 C99 및 이후에 정확하게 금지됩니다.(서문, 5 단락, _ "암시적인 int 제거"_ C99 표준에 있음).

기존의 이유로 인해 컴파일러는 암시 적 int 규칙을 계속 지원하므로 컴파일러와 실제 함수 정의에 의한 가정이 일치하지 않아 잘 컴파일됩니다. 그러면 undefined behavior이 호출됩니다. 함수가합니다 ( 표현) 유형과 호환되지 않는 유형이 정의되면

C11 챕터 §6.5.2.2 인용 함수

호출은 표현이 가리키는 그 호출 된 함수를 나타내며, 동작은 입니다.

+0

암시 적 int 규칙을 제거한 것은 C11 이었습니까? 그러나 나는 확실하지 않다. C99 일 수 있습니다. – StoryTeller

+0

@StoryTeller 아니, 나는 그것이 C99라고 확신한다. :) –

+0

오, 나는 C99를 조사 할 필요가 없다. 그것이 허용되었을 때조차도 나쁜 생각 이었기 때문에 어떤 방식 으로든 상관 없습니다. – StoryTeller