Ich habe gerade gelesen
ISO / IEC 9899: 201x Ausschussentwurf - 12. April 2011
in dem ich unter 5.1.2.2.3 Programmbeendigung gefunden habe
..reaching the } that terminates the main function returns a value of 0.
Dies bedeutet, dass wenn Sie keine return-Anweisung in angeben main()
und das Programm erfolgreich ausgeführt wird, in der schließenden Klammer} von main 0 zurückgegeben wird.
Aber im folgenden Code gebe ich keine return-Anweisung an, aber es gibt keine 0 zurück
#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);
}
kompilieren
gcc test.c
./a.out
sum is 15
echo $?
9 // here it should be 0 but it shows 9 why?
gcc
selbst (für Version 4.6.2) kompiliert eine Sprache, die C sehr ähnlich, aber nicht ganz ähnlich ist. Sie kompiliert GnuC89 - eine Sprache, die "lose" auf C89 basiert.return
Anweisung insum()
sind nicht erforderlich.int main()
sollte seinint main(void)
.Antworten:
Diese Regel wurde in der 1999er Version des C-Standards hinzugefügt. In C90 ist der zurückgegebene Status undefiniert.
Sie können es aktivieren, indem Sie es
-std=c99
an gcc übergeben.Als Randnotiz wird interessanterweise 9 zurückgegeben, da es die Rückgabe ist, von
printf
der gerade 9 Zeichen geschrieben wurden.quelle
return 0;
vor dem Schließen hinzufügen}
. Es ist harmlos und macht Ihr Programm für ältere Compiler portierbar.eax
insbesondere auf x86.eax
Register zurück. Weitere Informationen finden Sie unter en.wikipedia.org/wiki/X86_calling_conventions#cdecl .Es gibt einen Rückgabewert zurück,
printf
dessen Anzahl der wirklich ausgedruckten Zeichen ist.quelle
%errorlevel%
in Windows einchecken soll , gibt es einen Unterschied zwischen dem Exit-Code und dem Rückgabewert vonmain
unter Linux?printf
dem in diesem Fall 9 ist, der dannmain
bei Verwendung bestimmter gcc-Versionen irgendwie als Exit-Code "heraufgestuft" wird .Der Rückgabewert einer Funktion wird normalerweise im eax-Register der CPU gespeichert, daher die Anweisung "return 4;" würde in der Regel zu kompilieren
und return x (abhängig von Ihrem Compiler) wäre ungefähr so:
Wenn Sie keinen Rückgabewert angeben, spuckt der Compiler weiterhin das "ret" aus, ändert jedoch den Wert von eax nicht. Der Anrufer wird also denken, dass alles, was zuvor im eax-Register verblieben ist, der Rückgabewert ist. In diesem Beispiel ist dies normalerweise der Rückgabewert printf, aber verschiedene Compiler generieren unterschiedlichen Maschinencode und verwenden einige Register unterschiedlich.
Dies ist eine vereinfachte Erklärung. Unterschiedliche Aufrufkonventionen und Zielplattformen spielen eine wichtige Rolle. Es sollten jedoch genügend Informationen vorhanden sein, um zu erklären, was in Ihrem Beispiel „hinter den Kulissen“ geschieht.
Wenn Sie ein grundlegendes Verständnis von Assembler haben, lohnt es sich, die Demontage verschiedener Compiler zu vergleichen. Möglicherweise löschen einige Compiler das eax-Register als Schutz.
quelle