it-swarm.com.de

Warum kann `main` kein Double oder String zurückgeben, anstatt int oder void?

In vielen Sprachen wie C, C++ und Java hat die Methode/Funktion main den Rückgabetyp void oder int, jedoch nicht double oder String. Was könnten die Gründe dafür sein?

Ich weiß ein wenig, dass wir das nicht können, weil main von der Laufzeitbibliothek aufgerufen wird und eine Syntax wie int main() oder int main(int,char**) erwartet, also müssen wir bleiben dazu.

Meine Frage lautet also: Warum hat main die Typensignatur, die es hat, und keine andere?

38
JAVA

Der Rückgabewert von main ist auf einheitliche Weise an das Betriebssystem ( jedes Betriebssystems) zu übergeben. Das Betriebssystem muss wissen, ob das Programm erfolgreich beendet wurde oder ob ein Fehler aufgetreten ist.

Wenn dies eine Zeichenfolge ist, wird die Antwort in verschiedenen Sprachen schwierig. Die Interna eines Pascal-Strings (erstes Byte ist Länge) und eines FORTRAN-Strings (fest, auf einen bestimmten Wert aufgefüllt) und eines C-Strings (nullterminiert) sind alle unterschiedlich. Dies würde die Rückgabe eines konsistenten Werts an das Betriebssystem schwierig machen. Unter der Annahme, dass dies gelöst wurde, was würden Sie tun, um die Frage zu beantworten, die das Betriebssystem an das Programm gestellt hat? String-Vergleiche sind mit Fehlern behaftet ("Erfolg" vs "Erfolg"), und obwohl der Fehler für einen Menschen nützlicher sein kann, ist es für das Betriebssystem oder ein anderes Programm (Shell) schwieriger, damit umzugehen. Es gab auch signifikante Unterschiede sogar in den Zeichenfolgen selbst - EBCDIC (mit all seinen Codepages) gegenüber ASCII.

Floats und Doubles bieten keinen zusätzlichen Wert über die Ganzzahl für die Rückübertragung von Daten an das Betriebssystem (und die Shell). Zum größten Teil befasst sich keiner dieser Teile des Computers mit Gleitkommazahlen. Doppel sind auch nicht aufzählbar, was Vergleiche schwierig macht. Da sie nicht aufzählbar sind, melden sie den Fehler (vorausgesetzt, Sie haben einen bestimmten Wert für den Erfolg ausgewählt). Auch hier sind Gleitkommazahlen nicht konsistent - ein Gleitkommawert auf einem 8-Bit-Computer war anders als der Gleitkommawert auf einem 16-Bit- und einem 32-Bit-Computer (und dies sind nur die "normalen" - selbst innerhalb von IBM war der Gleitkommawert nicht standardisiert zwischen Maschinen desselben Herstellers bis in die 1980er Jahre). Und dann haben Sie Dezimal- und Binärcomputer. Gleitkommawerte sind nicht konsistent und liefern keine aussagekräftigen Daten zurück.

Das lässt uns wirklich das Byte und die ganze Zahl als Optionen. Die Konvention, die festgelegt wurde, war '0', war Erfolg, und alles andere war ein Fehler. Eine Ganzzahl bietet mehr Platz als ein Byte für die Meldung des Fehlers. Es kann aufgezählt werden (Rückgabe von 1 bedeutet XYZ, Rückgabe von 2 bedeutet ABC, Rückgabe von 3 bedeutet DEF usw.) oder als Flags verwendet werden (0x0001 bedeutet, dass dies fehlgeschlagen ist, 0x0002 bedeutet, dass fehlgeschlagen, 0x0003 bedeutet, dass sowohl dies als auch das fehlgeschlagen ist). Wenn Sie dies auf nur ein Byte beschränken, können leicht die Flags (nur 8) ausgehen, sodass die Entscheidung wahrscheinlich darin bestand, eine Ganzzahl zu verwenden.

88
user40980

Nun, es könnte .

Zum Beispiel wird im Dialekt von C, der im Betriebssystem Plan 9 verwendet wird, main normalerweise als void -Funktion deklariert, aber der Exit-Status wird an den Aufruf zurückgegeben Umgebung durch Übergeben eines Zeichenfolgenzeigers an die Funktion exits(). Die leere Zeichenfolge zeigt den Erfolg an, und jede nicht leere Zeichenfolge zeigt einen Fehler an. Dieses könnte implementiert worden sein, indem main ein char* Ergebnis zurückgegeben hat.

Und es wäre sicherlich möglich, ein System mit einem Exit-Status float oder double zu implementieren.

Warum also int? Es ist nur eine Frage der Konvention - und es hat einen enormen Wert, wenn Betriebssysteme und Programme, die unter ihnen ausgeführt werden, einer gemeinsamen Konvention folgen.

Die Unix-Konvention besteht darin, einen ganzzahligen Statuscode zu verwenden, wobei 0 für Erfolg und ungleich Null für Fehler steht (da es normalerweise nur einen Weg zum Erfolg gibt, aber mehrere Wege zum Scheitern). Ich weiß nicht, ob diese Konvention von Unix stammt; Ich vermute, es kam von früheren Betriebssystemen.

Gleitkomma wäre eine schwierigere Konvention, da (a) die Gleitkommaunterstützung nicht universell ist, (b) es schwieriger ist, eine Zuordnung zwischen Gleitkommawerten und Fehlerbedingungen zu definieren, (c) verschiedene Systeme unterschiedliche Gleitkommawerte verwenden Punktdarstellungen und (d) Stellen Sie sich vor, wie viel Spaß es macht, einen Rundungsfehler im Exit-Status Ihres Programms aufzuspüren. Ganzzahlen eignen sich dagegen sehr gut zur Aufzählung von Fehlercodes.

Plan 9 verwendet, wie bereits erwähnt, Zeichenfolgen, was jedoch eine gewisse Komplexität für die Speicherverwaltung, die Zeichenkodierung usw. mit sich bringt. Soweit ich weiß, war dies eine neue Idee, als Plan 9 sie implementierte, und sie ersetzte nicht die vorhandene weit verbreitete Konvention.

(Übrigens kann in C++ main nur int zurückgeben, und in C void main Ist zulässig Nur wenn der Compiler dies ausdrücklich unterstützt. Viele Compiler beschweren sich nicht sehr laut, wenn Sie void main schreiben, aber es ist nur eine leichte Übertreibung zu sagen, dass es falsch ist .)

29
Keith Thompson

Der von der Hauptmethode zurückgegebene Wert ist ein "Exit-Code". Es wird von der Aufruferanwendung (normalerweise Bash) verwendet, um zu testen, ob das Programm wie erwartet beendet wurde. Die Rückgabe einer Ganzzahl ist der einfachste Weg, dies auf Betriebssystemebene zu tun. Double macht für Fehlercode keinen Sinn und ein String ist auf Betriebssystemebene schwer zu pflegen (es gibt keinen GC).

9
xeranic