Dlaczego main nie zwraca tutaj 0?

Właśnie czytałam

ISO / IEC 9899: 201x projekt Komitetu-kwiecień 12, 2011

W którym znalazłem pod 5.1.2.2.3 zakończenie programu

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

Oznacza to, że jeśli nie podasz żadnej instrukcji return w main(), a jeśli program uruchomi się pomyślnie, to na nawiasie zamykającym } main zwróci 0.

Ale w poniższym kodzie nie podaję żadnej instrukcji return, jednak nie zwraca ona 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);
}

Compile

gcc test.c  
./a.out
sum is 15
echo $?
9          // here it should be 0 but it shows 9 why?
Author: Jeegar Patel, 2011-12-30

3 answers

Zasada ta została dodana w wersji C z 1999 roku. W C90 zwracany status jest niezdefiniowany.

Możesz go włączyć przekazując -std=c99 do gcc.

Na marginesie, co ciekawe 9 jest zwracane, ponieważ jest to Zwrot printf, który właśnie napisał 9 znaków.

 140
Author: cnicutar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-30 08:46:03

Zwraca zwracaną wartość printf, która jest liczbą rzeczywiście wydrukowanych znaków.

 15
Author: Summer_More_More_Tea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-30 08:45:39

Wartość zwracana z funkcji jest zwykle przechowywana w rejestrze EAX procesora, więc polecenie "return 4;" Zwykle kompiluje się do

mov eax, 4;
ret;

I return x (w zależności od kompilatora) będzie coś w stylu:

mov eax, [ebp + 4];
ret;

Jeśli nie podasz wartości zwracanej, kompilator nadal wypluwa "ret", ale nie zmienia wartości eax. Więc rozmówca pomyśli, że to, co kiedykolwiek zostało wcześniej w rejestrze eax, jest wartością zwracaną. Dla tego przykładu byłoby zwykle jest to zwracana wartość printf, ale różne Kompilatory będą generować inny kod maszynowy i inaczej używać niektórych rejestrów.

Jest to uproszczone wyjaśnienie, różne konwencje wywołania i platformy docelowe będą odgrywać istotną rolę, ale powinno to wystarczyć, aby wyjaśnić, co dzieje się "za kulisami" w twoim przykładzie.

Jeśli masz podstawową wiedzę na temat assemblera, warto porównać demontaż różnych kompilatorów. Może się okazać, że niektóre Kompilatory czyszczą rejestr eax jako zabezpieczenie.

 6
Author: noggin182,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-03 17:58:13