[c] 왜 main이 여기서 0을 반환하지 않습니까?

나는 방금 읽고 있었다

ISO / IEC 9899 : 201x위원회 초안 — 2011 년 4 월 12 일

5.1.2.2.3 프로그램 종료에서 발견 한

..reaching the } that terminates the main function returns a value of 0. 

에서 return 문을 지정하지 않고 main()프로그램이 성공적으로 실행되면 main의 닫는 중괄호}에서 0을 반환합니다.

그러나 다음 코드에서는 return 문을 지정하지 않았지만 0을 반환하지 않습니다.

#include<stdio.h>
int sum(int a,int b)
{
return (a + b);
}

int main()
{
    int a=10;
    int b=5;
    int ans;    
    ans=sum(a,b);
    printf("sum is %d",ans);
}

엮다

gcc test.c  
./a.out
sum is 15
echo $?
9          // here it should be 0 but it shows 9 why?



답변

이 규칙은 1999 년 버전의 C 표준에 추가되었습니다. C90에서 반환 된 상태는 정의되지 않았습니다.

-std=c99gcc 로 전달 하여 활성화 할 수 있습니다 .

부수적으로, 흥미롭게도 9 printf개 문자를 썼던 리턴이므로 9가 리턴 됩니다.


답변

printf실제로 인쇄 된 문자의 수인 반환 값을 반환합니다 .


답변

함수의 반환 값은 일반적으로 cpu의 eax 레지스터에 저장되므로 “return 4;”문은 일반적으로 컴파일됩니다

mov eax, 4;
ret;

반환 x (컴파일러에 따라 다름)는 다음과 같습니다.

mov eax, [ebp + 4];
ret;

반환 값을 지정하지 않으면 컴파일러는 여전히 “ret”을 뱉어 내지 만 eax의 값을 변경하지 않습니다. 따라서 호출자는 이전에 eax 레지스터에 남은 것이 반환 값이라고 생각할 것입니다. 이 예제의 경우 일반적으로 반환 값 printf이지만 다른 컴파일러는 다른 기계 코드를 생성하고 일부 레지스터를 다르게 사용합니다.

이것은 간단한 설명이며, 다양한 호출 규칙과 대상 플랫폼이 중요한 역할을 할 것이지만 예제에서 ‘뒤에서’무슨 일이 일어나고 있는지 설명하기에 충분한 정보 여야합니다.

어셈블러에 대한 기본적인 이해가 있다면 다른 컴파일러의 디스 어셈블리를 비교할 가치가 있습니다. 일부 컴파일러는 보호 수단으로 eax 레지스터를 지우고 있음을 알 수 있습니다.


답변