break; langsamer als exit() ?



  • SomeoneWithAQuestion schrieb:

    Allerdings wurde mir gesagt, dass in dem Fall des break; statements trotzdem noch jedes einzelne Statement darunter abgegrast wird - zwar im Sinne eines NOP, also leeren statements, aber bei meheren statements unter dem break; könnte das trotzdem ins Gewicht fallen.

    Das ist Quatsch.



  • Nach dem Verlassen einer Schleife durch break wird nichts mehr in der Schleife gemacht. Punkt.



  • Allerdings wurde mir gesagt, dass in dem Fall des break; statements trotzdem noch jedes einzelne Statement darunter abgegrast wird

    Völliger Blödsinn.

    Der Unterschied zwischen return 0 (also in deinem Beispiel dem break ) und exit(0) ist der:

    N3337 §3.6.1 / 4, exit()

    Terminating the program without leaving the current block (e.g., by calling the function std::exit(int)
    (18.5)) does not destroy any objects with automatic storage duration (12.4).

    Und das return -Statement in der main() :
    N3337 §3.6.1 / 5

    A return statement in main has the effect of leaving the main function (destroying any objects with automatic
    storage duration) and calling std::exit with the return value as the argument.

    Man sieht also, das return Statement ist möglicherweise langsamer.

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

    Damit kenne ich mich nicht aus, schätze aber dass man das Springen an sich hier vernachlässigen kann...



  • 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? 😉


Anmelden zum Antworten