break; langsamer als exit() ?



  • Okay okay, dann hatt mich meine bisherige Vorstellung doch nicht getäuscht.

    Dass das return eventuell langsamer als der exit-Befehl ist, nimmt man wahrscheinlich im Blick auf den Grund dafür gerne in Kauf 😛

    Auf jeden Fall Danke an Euch für die Aufklärung 😉 Mfg



  • Wen interessiert schon, wieviele Nanosekunden das return(0) eventuell langsamer ist? Beende dein Programm einfach vernünftig und baue bloß nicht solche Pseudo-Optimierungen ein. 🙂



  • _matze schrieb:

    Wen interessiert schon, wieviele Nanosekunden das return(0) eventuell langsamer ist? Beende dein Programm einfach vernünftig und baue bloß nicht solche Pseudo-Optimierungen ein. 🙂

    Das ist sogar AFAIR UB, oder? Falls Destruktoren nicht aufgerufen werden?



  • Wie kann ein beendetes Programm UB hervorrufen?



  • AFAIR UB schrieb:

    Wie kann ein beendetes Programm UB hervorrufen?

    Stimmt, zu dem Zeitpunkt zu dem es beendet ist kann kein UB mehr auftreten.



  • SomeoneWithAQuestion schrieb:

    Ich dachte, dass das break; statement in dem Fall einfach - in Assembler übersetzt - ein jmp hinter den Körper der while-schleife ist.

    break; entspricht einem Short Jmp. Opcode: 0xEB

    #include <iostream>
    using namespace std;
    
    int main()
    {
    int e;
    cin>>e;
    
            switch(e)
            {
            case 1:
                    cout<<"suung 1 ";
            break;
    
            case 2:
                    cout<<"suung 2"<<endl;
            break;
    
            case 3:
                    cout<<"sunng 3"<<endl;
            break;
    
            }
    
    system("PAUSE");
    return 0; 
    }
    

    Disassembly:

    00401168 > . 55             PUSH EBP
    00401169   . 8BEC           MOV EBP,ESP
    0040116B   . 51             PUSH ECX
    0040116C   . 8D45 FC        LEA EAX,DWORD PTR SS:[EBP-4]
    0040116F   . 50             PUSH EAX
    00401170   . FF35 9C614000  PUSH DWORD PTR DS:[<&STLP45.#1090_@_STL@>;  STLP45.@_STL@cin
    00401176   . E8 7D000000    CALL Project2.@_STL@%basic_istream$c20_S>
    0040117B   . 83C4 08        ADD ESP,8
    0040117E   . 8B55 FC        MOV EDX,DWORD PTR SS:[EBP-4]
    00401181   . 4A             DEC EDX                                  ;  Switch (cases 1..3)
    00401182   . 74 08          JE SHORT Project2.0040118C
    00401184   . 4A             DEC EDX
    00401185   . 74 1A          JE SHORT Project2.004011A1
    00401187   . 4A             DEC EDX
    00401188   . 74 3A          JE SHORT Project2.004011C4
    0040118A   . EB 59          JMP SHORT Project2.004011E5
    0040118C   > 68 A4304000    PUSH Project2.004030A4                   ; /Arg2 = 004030A4 ASCII "suung 1 "; Case 1 of switch 00401181
    00401191   . FF35 A0614000  PUSH DWORD PTR DS:[<&STLP45.#1091_@_STL@>; |Arg1 = 003A8AD0
    00401197   . E8 B4000000    CALL Project2.@_STL@$blsh$qr44_STL@%basi>; \@_STL@$blsh$qr44_STL@%basic_ostream$c20_STL@%char_traits$c%%pxc$r44_STL@%basic_ostream$c20_STL@%char_traits$c%%
    0040119C   . 83C4 08        ADD ESP,8
    0040119F   . EB 44          JMP SHORT Project2.004011E5
    004011A1   > 68 48164000    PUSH Project2.@_STL@%endl$c20_STL@%char_>;  Case 2 of switch 00401181
    004011A6   . 68 AD304000    PUSH Project2.004030AD                   ; /Arg2 = 004030AD ASCII "suung 2"
    004011AB   . FF35 A0614000  PUSH DWORD PTR DS:[<&STLP45.#1091_@_STL@>; |Arg1 = 003A8AD0
    004011B1   . E8 9A000000    CALL Project2.@_STL@$blsh$qr44_STL@%basi>; \@_STL@$blsh$qr44_STL@%basic_ostream$c20_STL@%char_traits$c%%pxc$r44_STL@%basic_ostream$c20_STL@%char_traits$c%%
    004011B6   . 83C4 08        ADD ESP,8
    004011B9   . 50             PUSH EAX                                 ; |Arg1
    004011BA   . E8 85000000    CALL Project2.@_STL@%basic_ostream$c20_S>; \@_STL@%basic_ostream$c20_STL@%char_traits$c%%@$blsh$qpqr44_STL@%basic_ostream$c20_STL@%char_traits$c%%$r44_STL@%basic_ostream$c20_STL@%char_traits$c%%
    004011BF   . 83C4 08        ADD ESP,8
    004011C2   . EB 21          JMP SHORT Project2.004011E5
    004011C4   > 68 48164000    PUSH Project2.@_STL@%endl$c20_STL@%char_>;  Case 3 of switch 00401181
    004011C9   . 68 B5304000    PUSH Project2.004030B5                   ;  ASCII "sunng 3"
    004011CE     FF             DB FF
    004011CF     35             DB 35                                    ;  CHAR '5'
    004011D0 > . A0614000       DD <&STLP45.#1091_@_STL@cout>
    004011D4   . E8 77000000    CALL Project2.@_STL@$blsh$qr44_STL@%basi>; \@_STL@$blsh$qr44_STL@%basic_ostream$c20_STL@%char_traits$c%%pxc$r44_STL@%basic_ostream$c20_STL@%char_traits$c%%
    004011D9   . 83C4 08        ADD ESP,8
    004011DC   . 50             PUSH EAX                                 ; |Arg1
    004011DD   . E8 62000000    CALL Project2.@_STL@%basic_ostream$c20_S>; \@_STL@%basic_ostream$c20_STL@%char_traits$c%%@$blsh$qpqr44_STL@%basic_ostream$c20_STL@%char_traits$c%%$r44_STL@%basic_ostream$c20_STL@%char_traits$c%%
    004011E2   . 83C4 08        ADD ESP,8
    004011E5   > 68 BD304000    PUSH Project2.004030BD                   ; /command = "PAUSE"; Default case of switch 00401181
    004011EA   . E8 AD130000    CALL <JMP.&CC3260._system>               ; \_system
    004011EF   . 59             POP ECX
    004011F0   . 33C0           XOR EAX,EAX
    004011F2   . 59             POP ECX
    004011F3   . 5D             POP EBP
    004011F4   . C3             RETN
    


  • suung schrieb:

    break; entspricht einem Short Jmp. Opcode: 0xEB

    tja, was soll ich sagen? hoffentlich taugt der wein den ich dieses jahr eingelagert hab mehr als die kommentare, sonst muss ich ihn wegschütten 👎



  • -.- Du glaubst es nicht oder?



  • Hier ein Bild aus dem Debugger meiner IDE: http://www7.pic-upload.de/09.11.12/cej3g1y7jr5o.png



  • na prima. dann hab ich mich getäuscht... soll ja auch mal vorkommen 🙄



  • Ich kannte das von Opera (inzwischen passiert das nicht mehr). Wegen Flash und anderem Krams hatte Opera 2GB RAM auf einem Rechner belegt, der nur 1GB hatte. Da es aber auf die Festplatte ausgelagert wurde hat sich das nicht sonderlich auf die Performance ausgewirkt. Wenn man aber Opera geschlossen hat, dann hat er die ganzen 2 GB stückweise reingeswappt, nur um sie freizugeben. Das hat etwa eine Minute gedauert und ich hätte mir gewünscht, dass die einfach exit() aufrufen wenn man das Fenster schließt statt aus der main zurückzukehren.



  • auf der anderen seite machst du das auffinden von memleaks fast unmöglich, weil ein exit() nichts aufräumt und der counter dann sicher nicht auf 0 steht. außer das programm ist klein.

    wie dumm von mir, wir haben ja schon geklärt, dass c++'ler keine memleaks produzieren ➡



  • Und wenn das Programm was systemglobales (z.B. Mutex) erzeugt, der dann wegen exit nicht wieder aufgeräumt wird? Oder wenn man auf einem Betriebssystem arbeitet, dass den Speicher eines Prozesses nicht automatisch bei Beenden freigibt? Die saubere Lösung ist return, Punkt.



  • .



  • suung schrieb:

    SomeoneWithAQuestion schrieb:

    Ich dachte, dass das break; statement in dem Fall einfach - in Assembler übersetzt - ein jmp hinter den Körper der while-schleife ist.

    break; entspricht einem Short Jmp. Opcode: 0xEB

    Blah
    break; entspricht dem was der Compiler draus macht. Das kann alles mögliche sein.



  • _matze schrieb:

    Und wenn das Programm was systemglobales (z.B. Mutex) erzeugt, der dann wegen exit nicht wieder aufgeräumt wird? Oder wenn man auf einem Betriebssystem arbeitet, dass den Speicher eines Prozesses nicht automatisch bei Beenden freigibt? Die saubere Lösung ist return, Punkt.

    Je nach System ist das vollkommen unproblematisch.
    Und die üblichen Systeme geben den Mist von Programmen frei die sich einfach so verabschieden.
    System-Resourcen aufräumen ist also meistens kein Problem.



  • hustbaer schrieb:

    _matze schrieb:

    Und wenn das Programm was systemglobales (z.B. Mutex) erzeugt, der dann wegen exit nicht wieder aufgeräumt wird? Oder wenn man auf einem Betriebssystem arbeitet, dass den Speicher eines Prozesses nicht automatisch bei Beenden freigibt? Die saubere Lösung ist return, Punkt.

    Je nach System ist das vollkommen unproblematisch.
    Und die üblichen Systeme geben den Mist von Programmen frei die sich einfach so verabschieden.
    System-Resourcen aufräumen ist also meistens kein Problem.

    Ist mir schon bewusst. Das war eher theoretisch betrachtet. Willst du hier eine Lanze für die exit-Variante brechen? 😉



  • _matze schrieb:

    Ist mir schon bewusst. Das war eher theoretisch betrachtet. Willst du hier eine Lanze für die exit-Variante brechen? 😉

    In gewisser Weise ja.
    Es gibt Fälle wo ich es für einen Fehler halte alles sauber aufzuräumen.
    Spontan fallen mir drei ein.

    1. Manchmal ist es sehr schwierig die korrekte Reihenfolge hinzubekommen in der Dinge freigegeben werden müssen. z.B. wenn man mit Singletons arbeitet. Ich bin zwar überhaupt kein Fan von Singletons (u.A. deswegen), aber es gibt auch Fälle wo man sich durch den Verzicht auf Singletons das Leben unnötig schwer macht. Manche Dinge ganz bewusst bei Programmende nicht freizugeben kann daher eine durchaus akzetable Lösung sein. Natürlich muss man aufpassen dass diese nicht-freigegebenen Dinge nichts wichtiges in ihrem Cleanup-Code machen. Wenn z.B. ein File offen ist, und der Cleanup-Code noch schnell gecachte Daten rausschreibt, dann sollte er auch aufgerufen werden. Wenn nur das File-Handle geschlossen wird kann man aber gerne darauf verzichten.

    2. Bei bestimmten Fehlern sollten mMn. keine Destruktoren aufgerufen werden. Nämlich dann wenn Invarianten verletzt wurden oder sonstige "assert-Artige" Fehler auftreten. Also Dinge die "eigentlich nicht passieren dürfen". Sich dann darauf zu verlassen dass der ganze Cleanup-Code nichts schlimmer macht als es bereits ist, ist mMn. oft ein Fehler.

    3. Es gibt das Konzept der sog. "crash only software". Wenn man seine Programme darauf auslegt, dass es nie irgendetwas gibt was beim Beenden noch schnell gespeichert/modifiziert/finalisiert/... werden müsste, dann besteht auch kein Grund alle Komponenten einzeln niederzufahren/aufzuräumen etc. In dem Fall kann man ruhig einfach exit() oder gar TerminateProcess() machen. Während des Entwickelns sollte man vermutlich trotzdem einen sauberen Shutdown-Pfad drinnen haben, z.B. um Leaks zu finden bzw. den Cleanup-Code von Komponenten zu testen (der ja trotzdem benötigt wird wenn bestimmte Komponenten während der Laufzeit aufgeräumt werden müssen).


Anmelden zum Antworten