Frage zu Return Werten



  • Hi Leute,
    ich habe heute begonnen die Grundlagen von C++ zu lernen (nud vor allem zu verstehen). Dazu orientiere ich mit an 'C++ - eine Einführung' von Ulrich Breymann. Dort wird als erstes Beispiel das typische 'Hello World' Programm erstellt:

    #include <iostream>
    int main(){
    	std::cout << "Hello World! \n";
    	return 0;
    }
    

    Und dazu hab ich eine anscheinend triviale Frage (zumindest konnte ich dazu keine hilfreiche Antwort finden). Also soweit ich das richtig verstanden habe, hat main() Funktion einen ganzzahligen Rückgabewert hat, der 0 ist, wenn das Programm korrekt durchgelaufen ist. Andernfalls ist der Wert ungleich 0.
    Meine Frage ist, was das return genau macht? Es macht keinen Unterschied, ob ich ich hinters return 0, 1 oder 2 schreibe. Das Programm läuft immer durch. Was hat es mit dem Rückgabewert von main() und dem Return-Wert genau auf sich?

    Für jeden Tipp wäre ich dankbar!



  • Die Rückgabe von main kann man z.B. in einem Shellscript (falls du Windows benutzt: Batchfile) abfragen, aus dem das Programm gestartet wurde. Per Konvention bedeutet der Wert 0, das das Programm erfolgreich seine Aufgabe ausgeführt hat, und alles andere, dass irgendwas schiefgelaufen ist. Außerhalb von Shellscripten und ähnlichem (z.B. Makefiles) ist das bedeutungslos.



  • Das ist für Batch-Dateien (bzw. Shell-Skripte) nützlich, um anhand des Rückgabewertes die weitere Abarbeitung zu steuern (dabei wird 0 als fehlerfrei angesehen), s.a. Exit status: Shell and scripts.



  • Danke für die schnellen Antworten! Gibt der Return Befehl dann den Rückgabewert von main() oder den hinter return stehenden Wert?



  • @Deuterium42 sagte in Frage zu Return Werten:

    Gibt der Return Befehl dann den Rückgabewert von main() rausgibt oder den hinter return stehenden Wert?

    Kannst du die Frage nochmal mit korrekter Grammatik stellen? Ich verstehe die beiden genannten Alternativen gar nicht. Der Rückgabewert ist das, was man zurückgibt, und zurückgeben tut man mit return.



  • Sorry für den Grammatikfehler! Ich versuche es nochmal anders: Wo ist der Unterschied zwischen

    #include <iostream>
    int main(){
       std::cout << "Hello World! \n";
       return 0;
    }
    

    und

    #include <iostream>
    int main(){
       std::cout << "Hello World! \n";
       return 1;
    }
    

    bzw. welchen Einfluss hat die explizite Wahl von 0 und 1 an dieser Stelle? Gebe ich damit selber an, ob mein Code (meiner Meinung nach) richtig arbeitet oder nicht?



  • Der Code arbeitet hoffentlich immer richtig. Du gibst damit an, ob das Programm seine Aufgabe erfolgreich erfüllt hat. Das hängt meistens von der Eingabe und von Umgebungsfaktoren ab, wenn z.B. eine als Kommandozeilenparameter angegebene Datei nicht existiert würde man einen Wert > 0 zurückgeben.



  • Alles klar! Vielen Dank!



  • Der Vollständigkeit halber möchte ich erwähnen, daß auf VMS ein exit code 1 für successful termination steht. Will man auf Nummer sicher gehen kann man auch EXIT_FAILURE und EXIT_SUCCESS aus <cstdlib> verwenden. Fehlt ein return-statement in main(), wird 0 zurückgegeben ("if execution reaches the closing curly bracket of main the effect is of the same as return 0;" oder so ähnlich).



  • Der Vollständigkeit halber muss man nun aber auch erwähnen, dass ein Rückgabewert von 0 äquivalent zu EXIT_SUCCESS ist und dem aufrufenden Prozess Erfolg signalisiert. Auch auf VMS, die Runtime muss das dann entsprechend transparent nach 1 übersetzen. Ist so, ich hab mir das nicht ausgedacht 🙂



  • @Bashar

    §7.20.4.3/5

    Finally, control is returned to the host environment. If the value of status is zero or EXIT_SUCCESS, an implementation-defined form of the status successful termination is returned. If the value of status is EXIT_FAILURE, an implementation-defined form of the status unsuccessful termination is returned. Otherwise the status returned is implementation-defined.



  • Äh ja, das ist genau das was ich gesagt habe und was du verschwiegen hast, oder?



  • @Bashar ja. Wenn ich aber den picky-mode auspacke steht da nirgends, daß EXIT_SUCCESS gleich 0 sein muss ;p

    // ach so, sonst gilt natürlich die Faustregel. Linkshändler benutzen die linke Faust, Rechtshändler die rechte. Und auf jeden Fall: Je höher desto platsch.



  • @Swordfish sagte in Frage zu Return Werten:

    @Bashar ja. Wenn ich aber den picky-mode auspacke steht da nirgends, daß EXIT_SUCCESS gleich 0 sein muss ;p

    Ja, das steht da nicht, und das hat auch niemand behauptet.



  • @Bashar sagte in Frage zu Return Werten:

    dass ein Rückgabewert von 0 äquivalent zu EXIT_SUCCESS ist

    habe ich so interpretiert.



  • "Äquivalent" ist was anderes als "gleich". Was soll ich dazu noch sagen.



  • @Swordfish sagte in Frage zu Return Werten:

    habe ich so interpretiert.

    dub di dub. ich sage ja nicht, daß das schlau war ...



  • @Deuterium42 Lass dich von dem Rückgabewert der Main-Funktion nicht verunsichern. Sobald du beim Lernen soweit fortgeschritten bist, dass du mit Funktionen beginnst wirst du ganz schnell verstehen für was Rückgabewerte sinnvoll sind. Der Rückgabewert der Main-Funktion ist für die nächst höhere Ebene gedacht. Also die Anwendung, welche dein Programm aufruft. So wie es schon geschrieben wurde. Ein kleines Beispiel hilft dir vielleicht:
    Stell dir vor, du schreibst ein Programm (MeinProgramm.exe) . Das Programm soll .zip Dateien entpacken. Dein Programm bekommt den Dateiname als Parameter übergeben. Nun kannst du (bei Windows) eine Batch Datei schreiben. "MeinProgramm.exe -Pictures.zip". Mit deiner Batch kannst du mit einem Befehl überprüfen was MeinProgramm.exe zurück gegeben hat. Läuft alles durch kommt zum Schluss in MeinProgramm.exe return 0;. Deine Batchdatei bekommt jetzt die 0 und gibt aus "Alles gut gegangen". Nun stell dir vor du hast keine Pictures.zip in dem Verzeichnis. Dann kannst du diesen Fall in MeinProgramm.exe abfragen und sagen return 1; (Wenn du in der Main-Funktion return... schreibst, dann endet dein Programm an der Stelle und macht nicht weiter) Deine Batch bekommt jetzt die 1. Nun könnte die Batch ausgeben "Ein Fehler ist aufgetreten, MeinProgramm.exe wurde vorzeitig beendet!".

    Ich hoffe ich hab das nicht zu umständlich geschrieben 🙂



  • Auf UNIX/Linux Systemen gibt es eine ganze Reihe fest definierter Returncodes, so dass man dem aufrufendem Programm damit mehr nur als Fehler oder Erfolg signalisieren kann. Allgemein sollte man den Inhalt von errno.h kennen und für spezielle Dienste sysexit.h.



  • @Deuterium42 sagte in Frage zu Return Werten:

    Gebe ich damit selber an, ob mein Code (meiner Meinung nach) richtig arbeitet oder nicht?

    wenn du später eigene funktionen erstellst, kannst du damit fehler abfragen. da werte von 0 immer "false" sind und alle werte ungleich 0 immer "true" kannst du dir dann sowas bauen:

    int MeineFunktion()
    {
         if(MeineUnterfunktion1())
         {
              return 1;
         }
    
         if(MeineUnterfunktion2())
         {
              return 2;
         }
    
         //////////////////
    
        return 0;
    }
    
    int main()
    {
         int rc = MeineFunktion();
    
         if(rc)
         {
         switch(rc)
         {
              case 1:
              cout << "MeineUnterfunktion1 fehlgeschlagen" << endl;
              return 1;
              break;
    
              case 2:
              cout << "MeineUnterfunktion2 fehlgeschlagen" << endl;
              return 2;
              break;
         }
         }
    
         cout << "keine Fehler in MeineFunktion aufgetreten" << endl;
         return 0;
    }
    

    die rückgabewerte kannst du übrigens nicht nur in shellscripten auswerten, sondern auch in c- oder c++-programmen, wenn du denn die entsprechende betriebssystemfunktion aufrufst, aber bis dahin hast du noch so einiges zu tun.