Präprozessor-Tutorial?



  • Hi Leute!
    Sagt mal, kennt ihr im Web ein gutes Tutorial über Präprozessor-Direktiven und wie man sie einsetzt? Ich möchte nämlich in meinem Programm durch einen Schalter gewisse Codeteile überspringen bzw. kompilieren, je nachdem wie der Schalter gesetzt ist. Es soll nämlich zwei Versionen von dem Programm geben, wobei sich diese in der Grundfunktion nicht unterscheiden, und extra den gesamten Code zu kopieren währe auch nicht die Ideallösung, besonders wenn man Fehler rausbaut, muss man es ja doppelt machen.

    Kennt ihr eine Lösung???

    Gruss, code_pilot 🙄



  • #ifdef
    #ifndef
    #define
    #else
    #endif

    was brauchst du mehr?



  • was brauchst du mehr?

    Durchblick 🙂

    Eine solche Aufgabe sollte man nicht unbedingt mit dem Präprozessor lösen.



  • Original erstellt von HumeSikkins:
    Eine solche Aufgabe sollte man nicht unbedingt mit dem Präprozessor lösen.

    Och. So ein einfaches -Dreduced_version muss man dem Compiler auf jeden Fall übergeben. Code verändern, das zu erledigen? Schlechte Idee. Eher sowas:

    template<int i> class XX { /* bla */ };
    template<> class XX<0> { /* blabla */ };
    #ifdef REDUCED
    typedef XX<0> XXd;
    #else
    typedef XX<1> XXd;
    #endif
    

    So ist die Verwendung des Präprozessors minimiert, die Bequemlichkeit eines Compiler-Schalters aber immer noch da. Oder fehlt mir der Durchblick? 🙂



  • Oder fehlt mir der Durchblick?

    Das kann ich nicht beurteilen.

    Wenn es mir auf schönen Code ankommt würde ich es aber eher so machen:

    // Datei: XY.h
    class XY
    {
    public:
    void bla();
    void blub();
    };
    
    // Datei: normal/XY.cpp
    #include "XY.h"
    void XY::bla() 
    {...}
    void XY::blub() 
    {...}
    
    // Datei: reduziert/XY.cpp
    #include "XY.h"
    void XY::bla() 
    {...}
    void XY::blub() 
    {...}
    
    // Datei: main.cpp
    #include "XY.h"
    
    int main()
    {
    XY x;
    x.bla();
    x.blub();
    }
    

    Dazu zwei z.B. Makefiles. Eins für die normale Konfiguration und eins für die reduzierte.

    Vielleicht interessiert dich das: http://www.chris-lott.org/resources/cstyle/ifdefs.pdf

    Und eine Suche in comp.lang.c++.moderated liefert zu diesem Thema auch sehr interessante Beiträge.



  • Original erstellt von HumeSikkins:
    Dazu zwei z.B. Makefiles. Eins für die normale Konfiguration und eins für die reduzierte.

    Scheint mir zu unbequem... Was spricht gegen die Template Version?
    Es geht ja fast genauso auch ohne Templates:
    im Header:

    class XYnormal { /* bla */ };
    class XYreduced { /* balaa */ };
    #ifdef REDUCED
    typedef XYreduced XY;
    #else
    typedef XYnormal XY;
    #endif
    

    und YEAH. (Templates oder so - Geschmackssache) Und das hat NICHTS mit Portabilität zu tun (will nich behaupten, deinen Link durchgelesen zu haben - aber das Vorwort hab ich angeschaut).



  • Wie lange bleibt es bei zwei Möglichkeiten? Wann werden es drei? Wann fünf?
    Und sind immer alle Möglichkeiten (eine Tiefe von 5 Ebenen führt bereits zu 32 möglichen Code-Pfaden) getestet oder wenigstens mal compiliert worden?

    Und das hat NICHTS mit Portabilität zu tun (will nich behaupten, deinen Link durchgelesen zu haben - aber das Vorwort hab ich angeschaut).

    Gerade im Zusammenhang mit portablen Code werden viele ifdefs-verwendet. Wenn es also um das Thema "Vermeidung von ifdefs" geht und ich möchte dies am Beispiel erklären, dann scheint das Beispiel Portabilität in meinen Augen eine gute Wahl zu sein.
    Ein anderes schönes Beispiel ist Tracing/Logging. James Kanze hat dieses in comp.lang.c++.moderated immer mal wieder verwendet.

    Naja, wie auch immer. Häufig ist es ganz gut, wenn man mehr als nur das Vorwort liest, bevor man eine endgültige Aussage macht. Aber das ist natürlich nur meine Meinung.



  • Original erstellt von HumeSikkins:
    Wie lange bleibt es bei zwei Möglichkeiten? Wann werden es drei? Wann fünf?
    Und sind immer alle Möglichkeiten (eine Tiefe von 5 Ebenen führt bereits zu 32 möglichen Code-Pfaden) getestet oder wenigstens mal compiliert worden?

    Und mehrere Code-Dateien helfen dabei? KLAR.



  • Und mehrere Code-Dateien helfen dabei? KLAR.

    ifdefs haben angeblich ähnlich wie switch-statements die Angewohnheit sich zu vermehren, damit das DRY-Principle zu verletzen und für Kopfschmerzen zu sorgen.
    Der Vorteil der mehreren Code-Datein sollte aus dieser Perspektive auf der Hand liegen. Du hast ein stabiles Interface und mehere varierende Implementationen.
    Die einzelnen Variationen befinden sich immer geschlossen an genau einem Ort.

    Ich habe also nicht dieses "oh-mann-hoffentlich-habe-ich-jetzt-alle-vorkommen-von-ifdef Elefant-gefunden-und-verbessert"-Problem.

    Aber ehrlich gesagt macht es mir keinen Spass mit dir zu diskutieren. Ich kann meine Arroganz ertragen und manchmal die von Volkard, aber deine ist derart penetrant, dass sie im Zusammenhang mit meiner für mich unerträglich wird.

    Du könntest ja z.B. begründen, warum du der Meinung bist, dass meine Aussagen schwachsinnig und meine Angaben auf externe Resource unnütz sind. Stattdessen kommt du aber nur mit großen Buchstaben. Das ist mir zu blöd.

    [ Dieser Beitrag wurde am 02.06.2003 um 15:01 Uhr von HumeSikkins editiert. ]



  • > ifdefs haben angeblich ähnlich wie switch-statements die Angewohnheit sich zu vermehren, damit das DRY-Principle zu verletzen und für Kopfschmerzen zu sorgen.
    sorry, aber was is das DRY principle?

    > Der Vorteil der mehreren Code-Datein sollte aus dieser Perspektive auf der Hand liegen. Du hast ein stabiles Interface und mehere varierende Implementationen. Die einzelnen Variationen befinden sich immer geschlossen an genau einem Ort.
    ??

    > Ich habe also nicht dieses "oh-mann-hoffentlich-habe-ich-jetzt-alle-vorkommen-von-ifdef Elefant-gefunden-und-verbessert"-Problem.
    Komisch. Ein einziges #ifdef, das die Variationen abgeht (mit typedefs) hielt ich immer für klein und elegant.

    > Aber ehrlich gesagt macht es mir keinen Spass mit dir zu diskutieren. Ich kann meine Arroganz ertragen und manchmal die von Volkard, aber deine ist derart penetrant, dass sie im Zusammenhang mit meiner für mich unerträglich wird.
    Hmm? Das is einfach mein Diskussions-Stil. Tatsächlich habe ich Respekt vor dir. Aber NIEMALS würde ich das in den Postings innerhalb einer Diskussion zeigen.

    > Du könntest ja z.B. begründen, warum du der Meinung bist, dass meine Aussagen schwachsinnig und meine Angaben auf externe Resource unnütz sind. Stattdessen kommt du aber nur mit großen Buchstaben. Das ist mir zu blöd.
    Ich bin der Meinung, dass deine Möglichkeit schlecht ist, weil meine zuerst da war und ich keinen Vorteil deiner sehe. Punkt. Mag sein, dass das kindisch is, aber das is mir sowas von egal.

    [ Dieser Beitrag wurde am 02.06.2003 um 15:19 Uhr von Mr. N editiert. ]



  • Ich finde es gibt Gründe die für beide Varianten sprechen. Je nachdem wie verschachtelt die ifdefs werden sollte man tatsächlich mit 2 dateien arbeiten und 2 makefiles erstellen. Wenn es nur darum geht ein einzelnes feature in einem build zu sperren finde ich dass Mr.N Recht hat wenn er sagt ifdefs wären einfacher. Aber dies hier ist auch wieder nur eine Meinung. Wie man es nachher macht liegt (zum Glück) in der Hand des Programmierers... 🙂


Anmelden zum Antworten