GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Warum gibt eine main-Funktion ohne return-Anweisung den Wert 12 zurück?

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.


Linux
  1. Warum gibt Find -mtime +1 nur Dateien zurück, die älter als 2 Tage sind?

  2. Wie funktioniert eine Gabelbombe?

  3. Was bedeutet Env X=() { :;}; Command’ Bash Do und warum ist es unsicher?

  4. Warum funktioniert die Variablenerweiterung ohne $ in Ausdrücken?

  5. Warum beginnt die Unix-Zeit am 1.1.1970?

Warum funktioniert `exit &` nicht?

Was gibt malloc(0) zurück?

CPU-Zyklen mit RDTSC erhalten - warum steigt der Wert von RDTSC immer?

Rückgabewert von x =os.system(..)

Warum gibt das Hinzufügen einer lokalen IP und eines Benutzernamens in scp einen Public-Key-Fehler zurück?

Rückgabewert der Timeout-Funktion