Почему main не возвращает 0 здесь?

Я просто читал

Проект ИСО/МЭК 9899: 201x - 12 апреля 2011 г.

в котором я нашел в соответствии с 5.1.2.2.3 Окончание программы

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

это означает, что если вы не укажете какой-либо оператор возврата в 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?

Ответ 1

Это правило было добавлено в версии стандарта стандарта C 1999 года. В C90 возвращается статус undefined.

Вы можете включить его, передав -std=c99 в gcc.

В качестве побочной заметки интересно 9 возвращается, потому что это возврат printf, который только что написал 9 символов.

Ответ 2

Возвращает возвращаемое значение printf, в котором действительно напечатано количество символов.

Ответ 3

Возвращаемое значение функции обычно сохраняется в регистре eax процессора, поэтому оператор "return 4;" обычно компилируется на

mov eax, 4;
ret;

и return x (в зависимости от вашего компилятора) будет что-то вроде:

mov eax, [ebp + 4];
ret;

если вы не укажете возвращаемое значение, тогда компилятор все равно выплюнет "ret", но не изменит значение eax. Таким образом, вызывающий может подумать, что ранее в регистре eax ранее было возвращаемое значение. Для этого примера обычно будет возвращаемое значение printf, но разные компиляторы будут генерировать разные машинные коды и использовать некоторые регистры по-разному.

Это упрощенное объяснение, различные вызовы и целевые платформы будут играть жизненно важную роль, но для этого достаточно информации, чтобы объяснить, что происходит "за кадром" в вашем примере.

Если у вас есть базовое понимание ассемблера, стоит сравнить разборку разных компиляторов. Вы можете обнаружить, что некоторые компиляторы очищают регистр eax как гарантию.