Unterschied zwischen Funktion und Makro ?



  • Doch, es gibt einen riesigen Unterschied beim Aufruf. Selbst wenn man den Mechanismus (Textersetzung beim Makro) mal außer Acht läßt: Die Argumente einer Funktion werden erst ausgewertet, dann wird die Funktion aufgerufen. Bei einem Makro passiert das nicht. Die Art und Weise, in der das Makro geschrieben ist, entscheidet, ob, wie oft und in welcher Reihenfolge die Argumente ausgewertet werden.



  • ich meinte auch nur die schreibweise, was sich im einzelnen dahinter versteckt glaub ich interessiert die wenigsten



  • Dann hast du nicht verstanden worauf ich hinauswill. Was, wenn ein Argument einen Seiteneffekt hat?



  • Nochmal zum Beispiel von oben und warum man Makros - wenn man sie überhaupt
    benutzen will - nur *sehr* vorsichtig benutzen soll:

    #define AREA(l,h) l * h
    
    int main()
    { 
        // Soll (2+3)*(4+6) = 5 * 10 = 50 ausgeben ...
        cout << AREA(2+3,4+6);
    }
    
    //nach Präprozessor:
    
    int main()
    { 
       // gibt aber 2+3*4+6 = 2+12+6 = 20 aus !!!
       cout << 2+3*4+6;
    }
    

    Das kann man umgehen, wenn man das Makro neu schreibt:

    #define AREA(l,h) ((l)*(h))
    

    Aber es gibt noch viele andere Schrecken und Teufeleien, die dir mit Makros
    passieren können (s. Bashar)!



  • jedoch sind makros ein bisschen schneller.

    Du hättest schreiben sollen, dass man inline-Funktionen einsetzen kann, die dann auch genauso schnell sind...



  • [EDIT]Zu langsam 🙂 [/EDIT]



  • Mis2com schrieb:

    jedoch sind makros ein bisschen schneller.

    Du hättest schreiben sollen, dass man inline-Funktionen einsetzen kann, die dann auch genauso schnell sind...

    Der größte Bullshit den ich je gelesen habe! Kennste sowas wie einen Profiler? Wenn ja würd ich an Deiner Stelle mal Deine lepsche Theorie mal erst Testen bevor Du hier so einen Schwachsinn postest. Zieh Dir erstmal den generierten Assembler code an und dann reden wir erst weiter.

    Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm, probier besser erstmal aus... So einen Schwachsinn gibts echt selten.

    Was behauptest Du als nächstes?

    class CX
    {
    public:
        inline void bar (void) { std::cout << "x" << std::endl; }
    };
    
    // ist im speed her äquivalent zu:
    
    #define BAR std::cout << "x" << std::endl;
    

    Merk Dir eines: Ob inline oder nicht, Funktionen kosten Zeit, zwar bei Inline weniger aber Zeit ist Zeit und Markos kosten nix an Zeit, da sie nicht aufgerufen werden sondern eingebunden werden.

    Ansonsten falls der Herr es ja nich glauben will: Zieh Dir den Assemblercode zu rate.



  • Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm,

    Doch.



  • nix da schrieb:

    Aber inline-Funktionen genau so schnell wie Makros? LOL nee komm, probier besser erstmal aus... So einen Schwachsinn gibts echt selten.

    Zeig doch einfach nur einmal einen Beweis her.
    Hier ist meiner:

    _main	PROC NEAR
    .B1.1:                          ; Preds .B1.0
    
    ;;; {
    
            push      ebx                                           ;9.1
            mov       ebx, esp                                      ;9.1
            and       esp, -16                                      ;9.1
    
    ;;;   std::cout<<"start\n";
    
            push      OFFSET FLAT: ??_C@_06A@start?6?$AA@           ;10.3
            push      OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;10.3
            call      ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;10.3
                                    ; LOE ebp esi edi
    .B1.2:                          ; Preds .B1.1
    
    ;;; 
    ;;;   {
    ;;;     std::cout<<"direkt im code\n";
    
            push      OFFSET FLAT: ??_C@_0BA@A@direkt?5im?5code?6?$AA@ ;13.5
            push      OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;13.5
            call      ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;13.5
                                    ; LOE ebp esi edi
    .B1.3:                          ; Preds .B1.2
    
    ;;;   }
    ;;; 
    ;;;   std::cout<<"halbzeit\n";
    
            push      OFFSET FLAT: ??_C@_09A@halbzeit?6?$AA@        ;16.3
            push      OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;16.3
            call      ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;16.3
                                    ; LOE ebp esi edi
    .B1.4:                          ; Preds .B1.3
    
    ;;; 
    ;;;   {
    ;;;     test();
    
            push      OFFSET FLAT: ??_C@_0BA@A@ich?5bin?5inline?6?$AA@ ;19.5
            push      OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;19.5
            call      ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;19.5
                                    ; LOE ebp esi edi
    .B1.5:                          ; Preds .B1.4
    
    ;;;   }
    ;;; 
    ;;;   std::cout<<"ende\n";
    
            push      OFFSET FLAT: ??_C@_05A@ende?6?$AA@            ;22.3
            push      OFFSET FLAT: ?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ;22.3
            call      ??6std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z ;22.3
                                    ; LOE ebp esi edi
    .B1.9:                          ; Preds .B1.5
            add       esp, 40                                       ;22.3
                                    ; LOE ebp esi edi
    .B1.6:                          ; Preds .B1.9
    
    ;;; }
    
            xor       eax, eax                                      ;23.1
            mov       esp, ebx                                      ;23.1
            pop       ebx                                           ;23.1
            ret                                                     ;23.1
            ALIGN     4
                                    ; LOE
    ; mark_end;
    _main ENDP
    

    Der C++ Code dazu:

    #include <iostream>
    
    inline int test()
    {
      std::cout<<"ich bin inline\n";
    }
    
    int main()
    {
      std::cout<<"start\n";
    
      {
        std::cout<<"direkt im code\n";
      }
    
      std::cout<<"halbzeit\n";
    
      {
        test();
      }
    
      std::cout<<"ende\n";
    }
    

    Ansonsten falls der Herr es ja nich glauben will: Zieh Dir den Assemblercode zu rate.

    Dies habe ich hiermit getan 🙂

    Ja, ich weiss, du willst nur trollen - aber damit habe ich dir wohl den Wind aus den Segeln genommen - obwohl die Idee garnicht mal schlecht ist, darauf zu bauen, dass alle zu faul sind dir einen Gegenbeweis zu bringen (und du selbst kannst ja keinen beweis bringen) - dann hast du eine Pattstellung und Newbies glauben dir dann vielleicht sogar.

    Nicht dumm, nicht dumm.



  • @Shade Of Mine
    Wahrscheinlich ist er einfach nur so verblendet, dass er nicht weiß, wie er seinen Compiler einstellen muss, damit dieser hübsch effizienten Code generiert. Kennt man ja: volles Mett Debug-Informationen anschalten (und Optimierung aus) und sich dann wundern, dass das Programm 20 MB groß ist und keine einzige Funktion inline generiert wird.



  • Shade: Man muss aber fairerweise sagen, dass das kein besonders gutes Beispiel ist. Mach dasselbe nochmal mit max().



  • Bashar schrieb:

    Shade: Man muss aber fairerweise sagen, dass das kein besonders gutes Beispiel ist. Mach dasselbe nochmal mit max().

    http://www.c-plusplus.net/forum/viewtopic.php?t=73480&start=15



  • Diese Diskussion sieht ja böse aus... 😉



  • Oder ihn hat die Freude daran mich fertigzumachen angetrieben, kommt nicht selten vor. 🙂


Anmelden zum Antworten