Compiler Macros = teh evil



  • Scorcher24 schrieb:

    Das Problem ist ja gelöst.
    Ich fand es nur so genial exemplarisch für einen Foreneintrag, weil es genau die Art von Makro ist, die man eben nicht schreiben soll.

    ACK

    Natürlich sind Makros was tolles wenn man sie sinnvoll einsetzt. Ich nutze sie ja auch.

    Na dann bin ich wieder beruhigt 🙂

    Aber ich prefixe meine Makros und gebe denen sinnvolle Namen, so dass Duplikate schwer werden.

    Sollte man auch machen. Es nicht zu machen wäre vergleichbar mit keine Namespaces zu verwenden, aber dafür schlechte und kurze Namen 🙂



  • Wie zum Beweis:
    Soeben hat hustbaer sinnvolle Makros gezeigt beim TMP-Logarithmus.
    http://www.c-plusplus.net/forum/285097-10



  • Nur für die Lulz:

    MySQL Package, config-win.h, Zeile 213:

    #define sleep(A)  Sleep((A)*1000)
    

    Ich meine, MySQL.. hallo? Die sollten es doch besser wissen :D.
    Aber okay, es wurde alles dazu gesagt :p.



  • Scorcher24 schrieb:

    #define sleep(A)  Sleep((A)*1000)
    

    Na, zumindest ist A sauber geklammert.
    Ich schreibe eigentlich keine Makros bzw. war nie in einer Situation, wo ich sagen würde, jetzt bräuchte ich ein Makro... und, wenn ich so überlege, habe ich nie ein Makro gesehen, wo ich mich erstaunt und flüsternd "geil, ist das nützlich" zurücklehen konnte. Im Gegenteil, immer nur drübergestolpert, und stolpere immer wieder drüber.
    Es gibt Sachen, bei denen man sich unfreiwillig fragt, warum hat sich eigentlich jemand für ein Makro entschieden, ein Makro, das irgendwie Information versteckt, nichts aussagt, einfach nur irgendwas vesteckt, wo man erstmal eine halbe Stunde lang suchen muss, um den Sinn zu verstehen.
    Man hat z.B. eine Reihe von Funktionen:

    static void power_on(void)
    {
        ...
    }
    static void power_off(void)
    {
        ...
    }
    ...
    

    und man fragt sich, wo werden sie eigentlich verwendet, denn es gibt keine Compiler-Warnung wie "unbenutzte statische Funktion" o.ä... dann schaut man erstmal weiter und wird irgendwann mal verzweifelt auf eine Zeile aufmerksam:

    FANCY_MACRO(blabla, on, off);
    

    dann sucht man nach FANCY_MACRO und findet so was:

    #define FANCY_MACRO(a, b, c) \
    struct power_struct power_##a \
    { \
        .on = power_##b, \
        .off = power_##c \
    }
    

    oder ähnlich, weiß nicht genau, ob das so richtig ist, der Sinn davon ist, es gibt eine Struktur mit Funktionszeigern on und off und mit dem Makro wird eine Struktur angelegt und die Funktionszeiger initialisiert. Das ist irgendwie von hinten durch die Brust ins Auge.
    Ich bin der Meinung, wenn Leute Makros schreiben, um sich die Tipparbeit zu ersparen - sollen sie andere für Programmierer geeignete Editoren benutzen, gvim oder emacs o.ä. Bei diesen Editoren, bei gvim zumindest, lässt sich die Tipparbeit schön automatisieren.
    Wenn sie Makros schreiben, um den Code schlau zu machen, damit es kürzer aussieht oder was auch immer - das ist ungut, minus gut. Je schlauer der Code, desto schwieriger für andere, den Code zu verstehen, zu warten, zu debuggen...



  • abc.w schrieb:

    #define FANCY_MACRO(a, b, c) \
    struct power_struct power_##a \
    { \
        .on = power_##b, \
        .off = power_##c \
    }
    

    oder ähnlich,

    Fürchterlich.
    Aber was ist mit diesen Makros?

    #define sin(x) sin((x)/180*PI)
    //bugfix, jetzt ist sin(90) endlisch wieder 1
    
    #define cout cout<<
    //endlich geht cout "hello, world\n";
    

    und mein Favorit

    #define retrun return
    //gegen den üblichsten tippfehler
    


  • volkard schrieb:

    und mein Favorit

    #define retrun return
    //gegen den üblichsten tippfehler
    

    Also ich kann mir keinen ernsthaften Programmierer vorstellen der so ein Makro verwendet :D.



  • volkard schrieb:

    Fürchterlich.
    Aber was ist mit diesen Makros?

    #define sin(x) sin((x)/180*PI)
    //bugfix, jetzt ist sin(90) endlisch wieder 1
    
    #define cout cout<<
    //endlich geht cout "hello, world\n";
    

    Dafür zerschmettert es mir sin(PI) und cout << "Hello World!" in altem Code. Im erstem Fall sogar ohne Compilefehler. Warum nicht wenigstens andere Namen?



  • ipsec schrieb:

    Dafür zerschmettert es mir ... in altem Code. Im erstem Fall sogar ohne Compilefehler.

    Hast recht, ich mache das dann wohl doch nicht.

    #include <iostream>
    #include <cmath>
    using namespace std;
    
    #define retrun return
    #define PI M_PI
    #define sin(x) sin((x)/180*PI)
    #define cout cout<<
    
    int main() {
        for(int i=0;i<=360;i+=30){
            cout "sin("<<i<<")="<<sin(i)<<'\n';
        }
        retrun 0;
    }
    

    Ausgabe:

    alles 0
    

    ipsec schrieb:

    Dafür zerschmettert es mir sin(PI) ... in altem Code.

    DAS konnte ich aber konsequent reparieren.

    #define sin(x) sin((x)/180*M_PI)
    #define PI 180.0
    


  • @ipsec
    Ich glaube nicht dass volkard seine letzten Beiträge ernst gemeint hat.

    @volkard
    Findest du jetzt Makros allgemein schlimm, und dein "Wie zum Beweis" Beitrag ist ironisch/zynisch/whatever zu verstehen? Oder findest du nur die Beispiele die du gebracht hast schlimm?
    (Was klar sein sollte: ein Name wie "TEST" für ein Makro hat in einem realen Projekt nix verloren. Für einen 100 Zeilen Codefetzen ist mir das aber eher egal.)



  • Dein TEST war ein Beispiel für ein sehr sinnvolles Makro.
    Meine Beispiel waren nicht ernst gemeint.


Anmelden zum Antworten