Nach dem Lesen der Antworten über das Thema Kontrolle erreicht das Ende der nicht-void Funktionen Ich habe keine Antwort speziell auf den Fall des Beendens einer nicht-void-Funktion mit einem leeren return
Aussage:
Was ich bisher im C-Standard gefunden habe ist:
6.8.6.4 Die return-Anweisung
Einschränkungen
- Eine
return
-Anweisung mit einem Ausdruck darf nicht in einer Funktion erscheinen, deren Rückgabetypvoid
ist. Einereturn
-Anweisung ohne einen Ausdruck darf nur in einer Funktion erscheinen, deren Rückgabetypvoid
ist.
Der Standardquotiertext gibt an, was wir mit unseren return
-Anweisungen für void
und nicht void
-Funktionen tun sollten. Was passiert, wenn wir die Einschränkung ignorieren, wird in einem anderen Teil des Dokument:
6.9.1 Funktionsdefinitionen
- Wenn das
}
, das eine Funktion beendet, erreicht wird und der Wert des Funktionsaufrufs vom Aufrufer verwendet wird, ist das Verhalten nicht definiert.
Das vorherige Standardzitat besagt, dass UB auftritt, wenn wir den zurückgegebenen Wert einer Funktion verwenden, die nach dem Erreichen der schließenden geschweiften Klammern endet ( }
), also haben wir UB im folgenden Code:
Im Aufruf UB(1)
gibt die Funktion 1
über die Anweisung return x;
unter if (x)
zurück; Im Aufruf UB(0)
wird die Bedingung if (x)
nicht übergeben, so dass die Funktion das Erreichen von }
beendet, damit der Rückgabewert in diesem Fall UB ist (aber nicht in UB(1)
). Aber was passiert in diesem Fall?
Im obigen Code erfüllt der Aufruf UB(1)
nicht die Anforderungen von §6.9.1/12
, um zu UB zu führen, da die Funktion beendet, ohne }
zu erreichen und auch keinen Wert zurückgibt.
In welchem Teil des C-Standards wird diese Situation beschrieben?
Dies ist nicht einmal undefiniertes Verhalten, es ist eine Einschränkung Verletzung . Der zitierte Text
Eine return-Anweisung ohne einen Ausdruck darf nur in a erscheinen Funktion, deren Rückgabetyp ungültig ist
von 6.8.6.4 ist normativ, was bedeutet, dass der Compiler es nicht durchlassen darf, ohne eine diagnostische Nachricht zu geben. Wenn es kompiliert wird, ohne eine Diagnose zu geben, ist der Compiler keine konforme Implementierung (folgt nicht dem Sprachstandard).
Im Klartext heißt das: Dieser Code sollte nicht einmal kompiliert werden.
Wenn der Compiler eine binäre ausführbare Datei erzeugt, selbst wenn der Code Constraint-Verletzungen aufweist, sind alle Wetten deaktiviert. Es ist nicht mehr ein C-Programm, sondern ein nicht-standardisiertes Programm, das von keinem Sprachstandard garantiert wird.