Ich antworte, weil alle vorhandenen Antworten sagen, dass es sich um ein undefiniertes Verhalten handelt, was nicht stimmt, also habe ich nichts, was ich positiv bewerten könnte.
In C89 (danke an pmg für den Hinweis auf einen Normentwurf), 5.1.2.2.3:
Eine Rückkehr vom ersten Aufruf zur Hauptfunktion entspricht dem Aufruf der Exit-Funktion mit dem von der Hauptfunktion zurückgegebenen Wert als Argument. Wenn das } erreicht wird, das die Hauptfunktion beendet, wird der Beendigungsstatus nicht angegeben, der an die Hostumgebung zurückgegeben wird.
In C99, Zitat aus n1256, 5.1.2.2.3:
Wenn der Rückgabetyp der Hauptfunktion ein innerhalb von t kompatibler Typ ist, entspricht eine Rückkehr vom ersten Aufruf der Hauptfunktion dem Aufruf der Exit-Funktion mit dem von der Hauptfunktion zurückgegebenen Wert als Argument; Das Erreichen von }, das die Hauptfunktion beendet, gibt den Wert 0 zurück. Wenn der Rückgabetyp nicht mit int kompatibel ist, ist der an die Hostumgebung zurückgegebene Beendigungsstatus nicht angegeben.
Es ist also kein "undefiniertes Verhalten":es verhält sich so, als ob main
Die Funktion kehrt zurück, aber in C89 ist der zurückgegebene Wert nicht durch den Standard spezifiziert. Für Ihr Beispielprogramm scheint der zurückgegebene Wert in Ihrer Implementierung konsistent 12 zu sein, vermutlich aus dem Grund, den Ben Voigt sagt. Da Sie unter Linux arbeiten, ist es wahrscheinlich keine große Änderung, Ihren Code als C99 zu kompilieren (oder jedenfalls mit dem fast kompatiblen C99-Modus von gcc zu kompilieren).
Für jede Funktion, die einen anderen Wert als main
zurückgibt , es ist undefiniertes Verhalten, es sei denn der Aufrufer verwendet den Rückgabewert nicht (n1256, 6.9.1/12):
Wenn das }, das eine Funktion beendet, erreicht wird und der Wert des Funktionsaufrufs vom Aufrufer verwendet wird, ist das Verhalten undefiniert.
Ich bin mir nicht sicher, ob der anfängliche Aufruf von main
sind als von dieser allgemeinen Regel ausgenommen zu erwähnen. Das muss nicht sein:Aus Sicht des Standards hat dieser Aufruf keinen Aufrufer, daher denke ich, dass der Wert des Funktionsaufrufs nicht "vom Aufrufer verwendet" wird, obwohl er zum Beendigungsstatus wird für das Programm.
Wie swegi sagt, ist es undefiniertes Verhalten. Wie Steve Jessop et al sagen, ist es ein unspezifizierter Wert bis C89 und spezifiziert in C99 (das beobachtete Verhalten ist nicht konform zu C99)
Was in den meisten Umgebungen tatsächlich passiert, ist, dass der Rückgabewert der letzten printf
wird in dem für Rückgabewerte verwendeten Register belassen.
Also 11 für n ==0, 12 wenn n einstellig ist, 14 für zweistelliges n, 16 für dreistelliges n usw.