Beginnend mit dem C99-Standard muss der Compiler das Äquivalent von a generieren return 0
oder return EXIT_SUCCESS
wenn nein Rückkehr wird am Ende geliefert main
. Etwa zur gleichen Zeit gab es auch eine entsprechende und identische Änderung am C++-Sprachstandard. Ich interessiere mich für die Gründe für beide und ich schätzte, dass es unwahrscheinlich war, dass es sich um völlig getrennte und nicht zusammenhängende Änderungen handelte.
Meine Frage ist:
Was war die dokumentierte Begründung für diese Änderung?
Eine ideale Antwort würde maßgebliche Quellen für C und C++ zitieren, weshalb ich die Frage mit beiden Sprachen markiert habe.
Beachten Sie, dass ich im Gegensatz zu der Frage Was die Gründe für/gegen die Rückgabe von 0 von main in ISO C++? nicht um Rat frage, ob ich schreiben soll return 0
in meinen Programmen — ich frage, warum die Sprachstandards selbst geändert wurden.
Um den Zweck der Frage zu verstehen, hier ein bisschen mehr Kontext:
- Zu verstehen, warum eine Änderung vorgenommen wurde, ist hilfreich bei der Entscheidung, wie sie verwendet werden soll.
- Die Begründung ist häufig in der Norm selbst enthalten. Zum Beispiel enthält der C90-Standard viele erläuternde Fußnoten, wie Fußnote 36, die mit „Die Absicht dieser Liste …“ beginnt.
Ich habe die Standards studiert und selbst nach der Antwort gesucht, bevor ich hier gefragt habe, aber keine Antwort gefunden. Ich wurde gebeten, beim Schreiben von Codierungsstandards für beide Sprachen für eine Gruppe von Programmierern zu helfen, und ich wollte sicherstellen, dass ich verstehe, warum diese Funktion existiert, damit ich anderen ihre Verwendung genau erklären kann.
Im Der neue C-Standard Sektion 5.1.2.2.3 Programmbeendigung der Autor Derek Jones Kommentar zu diesen Zeilen aus dem C99-Standard:
Das Erreichen von }, das die Hauptfunktion beendet, gibt den Wert 0 zurück
ist:
Der Standard muss sich endlich schlampigen bestehenden Praktiken beugen.
Was darauf hinweist, dass der Grund darin bestand, schlechte Programmierpraktiken in Bezug auf die explizite Rückgabe eines Werts von anzugehen main
. Zuvor war der zurückgegebene Status undefiniert.
Er weist darauf hin, dass viele Implementierungen dies bereits in C90 implementiert haben, sodass die Tatsache, dass diese Änderung bereits die gemeinsame Implementierung widerspiegelte, wahrscheinlich auch geholfen hat.
Das offizielles Begründungsdokument für C99 geht darauf kaum ein. Anscheinend exit(0)
wurde der Standard für den Kontrollfluss am Ende der Hauptleitung, weil exit(0)
wurde eine aussagekräftige portable Semantik gegeben.
Hier sind die beiden relevanten Abschnitte:
5.1.2.2.1 Programmstart
Das Verhalten der Argumente zu main
und der Interaktion von exit
, main
und atexit
(siehe §7.20.4.2) wurde kodifiziert, um unerwünschte Vielfalt in der Darstellung einzudämmen argv
Zeichenfolgen und im Sinne von Werten, die von zurückgegeben werden main
.
Die Angabe von argc
und argv
Als Argumente erkennt man vor allem umfangreiche Vorpraktiken an.
argv[argc]
muss ein Nullzeiger sein, um eine redundante Prüfung für das Ende der Liste bereitzustellen, ebenfalls auf der Grundlage allgemeiner Praxis.
main
ist die einzige Funktion, die portabel mit null oder zwei Argumenten deklariert werden kann. (Die Anzahl der Argumente anderer Funktionen muss zwischen Aufruf und Definition genau übereinstimmen.) Dieser Sonderfall erkennt einfach die weit verbreitete Praxis an, die Argumente bis wegzulassen main
wenn das Programm nicht auf die Programmargumentzeichenfolgen zugreift. Während viele Implementierungen mehr als zwei Argumente unterstützen main
, eine solche Praxis wird vom Standard weder gesegnet noch verboten; ein Programm, das main mit drei Argumenten definiert, ist nicht strikt konform (siehe §J.5.1.).
Die Befehlszeilen-E/A-Umleitung wird vom Standard nicht vorgeschrieben, da dies als Funktion des zugrunde liegenden Betriebssystems und nicht der Sprache C angesehen wurde.
und
7.20.4.3 Die Ausgangsfunktion
Das Argument zu exit
ist eine Statusanzeige, die an die aufrufende Umgebung zurückgegeben wird. Im UNIX-Betriebssystem ist ein Wert von Null der erfolgreiche Rückkehrcode von einem Programm. Da sich die Verwendung von C über UNIX hinaus ausgebreitet hat, exit(0)
wurde oft als Redewendung beibehalten, die auf eine erfolgreiche Beendigung hinweist, auch auf Betriebssystemen mit unterschiedlichen Rückgabecodesystemen. Diese Verwendung wird somit als Standard anerkannt. Seit den Argumenten to exit
sind implementierungsdefiniert. Das EXIT_FAILURE
Makro wurde zu C89 hinzugefügt, um eine solche Fähigkeit bereitzustellen. EXIT_SUCCESS
wurde ebenfalls hinzugefügt.
Abgesehen von Anrufen, die explizit von einem Programmierer codiert wurden, exit
wird bei der Rückkehr von aufgerufen main
. Somit ist zumindest in diesem Fall der Körper von exit
kann nicht von der Existenz anderer Objekte mit automatischer Aufbewahrungsdauer als den in deklarierten ausgehen exit
.
Der Ausschuss prüfte die Hinzufügung von _exit
, lehnte es jedoch aufgrund von Bedenken hinsichtlich der Unvereinbarkeit mit der POSIX-Spezifikation ab, auf der es basiert. Eine geäußerte Sorge ist zum Beispiel die _exit
wurde als Möglichkeit angegeben, aus einem Signal-Handler herauszukommen, ohne ein weiteres Signal auszulösen, aber das ist eigentlich nicht der Weg _exit
verhält sich in POSIX-Umgebungen. Solche falschen Hoffnungen wollte das Komitee den Programmierern nicht machen. (Aber siehe §7.20.4.4 für C99.)
@Olaf: Sprachänderungsvorschläge werden normalerweise mit den Gründen für die vorgeschlagene Änderung dokumentiert. Ich bitte um diese Dokumentation, nicht für Spekulationen.
– Eduard
13. Juli 2015 um 22:07 Uhr
C++98 ging C99 voraus, also liegt die Antwort wahrscheinlich in WG21, nicht in WG14 … möglicherweise sogar in Vorstandard-C++, hat jemand das alte Buch?
– o11c
13. Juli 2015 um 22:23 Uhr
Dies müssen zwei Fragen sein, eine für C, eine für C++. Fühlen Sie sich frei, Links in jede Frage zur anderen einzufügen.
– Ben Voigt
13. Juli 2015 um 22:42 Uhr
Das Vorwort zum C99-Standard enthält eine Liste der “wichtigsten Änderungen” gegenüber der vorherigen Ausgabe. Die Änderung, die das Ende des Herunterfallens bewirkte
main
gleichwertigreturn 0;
wird nicht erwähnt, und der Abschnitt, in dem die Änderung vorgenommen wurde (5.1.2.2.3), bietet keine Begründung.– Keith Thompson
13. Juli 2015 um 23:03 Uhr
@Olaf das ist weder spekulativ noch meinungsbasiert. Änderungen an C und C++ werden als Teil des Standardprozesses vorgenommen und alle Änderungen haben eine Begründung. Es kann schwierig sein, ein öffentliches Dokument für einen bestimmten Fall zu finden, aber es gibt eine Begründung und es ist eine berechtigte Frage.
– Shafik Yaghmour
14. Juli 2015 um 4:01 Uhr