Macros in Klassendefinition



  • Hallo zusammen,

    ich hab mal eine kurze Nachfrage. Ist folgendes Szenario kritisch?

    In meiner Library habe ich folgende Klasse:

    TestThread.h:

    #ifndef TEST_THREAD_H_
    #define TEST_THREAD_H_
    
    #ifdef BOOST_THREAD_SUPPORT
    	boost::thread thread;
    #endif
    
    class TestThread {
    
    private:
    
    #ifdef BOOST_THREAD_SUPPORT
    	boost::thread thread;
    #endif
    
    	// ... andere class members (auch nach dem #ifdef)
    
    };
    
    #endif /* TEST_THREAD_H_ */
    

    TestThread.cpp:

    #define BOOST_THREAD_SUPPORT
    #include "TestThread.h"
    

    In meiner Anwendung möchte ich dann einfach TestThread.h includieren
    ohne boost-Library als include-Path.
    Muss ich irgendwelche Probleme befürchten? Mir ist klar dass ich bei
    statischen Libraries die Boost-Thread-Library mitlinken muss.
    (Bei dynamischen (glaub ich) nicht)

    Gruß,
    CSpille



  • Inwiefern kritisch? Makros werden durch den Präprozessor aufgelöst, also vor dem eigentlichen Kompiliervorgang. Und zu diesem Zeitpunkt kann von so etwas wie Klassen noch keine Rede sein...


  • Administrator

    Kritisch ist wahrscheinlich vor allem, dass nach der Konstruktion eins boost::thread Objekt, der Thread gleich gestartet wird. Also ein boost::thread als Klassenmember oder globale Variable dürfte wohl kaum das sein, was du willst 🙂

    Ansonsten dürfte vielleicht die Lektüre dieses Threads, den wir erst gerade kürzlich hatten, interessant für dich sein:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-236515.html

    Grüssli



  • Hallo zusammen,

    vielen Dank für eure Antworten.

    @Nexus: Die Reihenfolge der class members verändert sich ja und wenn Referenzen
    nur relativ zum Objekt ausgedrückt werden, dann würde ja auf einen anderen Speicherbereich gezeigt weden.

    @Dravere: Du hast absolut Recht. Ich hatte das Problem wohl unglücklich auf diesen
    Beispiel-Code übertragen ^^

    Gruß,
    CSpille



  • CSpille schrieb:

    ...

    Wenn ich Dich richtig verstehe, willst Du die Abhängigkeiten von boost::thread aus Deinem Header heraus haben.
    Das kannst Du durch Vorwärtsdeklaration lösen:

    //MyCrazyClass.h
    #include <memory>
    
    namespace boost
    {
        class thread;
    }
    
    class MyCrazyClass
    {
    public:
        MyCrazyClass
            ();
       //bla...
    private:
        std::auto_ptr<boost::thread> theThread;
    };
    
    //MyCrazyClass.cpp
    MyCrazyClass
        ( )
        : theThread(new boost::thread(thread_fkt)
    { }
    
    //...
    

  • Administrator

    CSpille schrieb:

    @Nexus: Die Reihenfolge der class members verändert sich ja und wenn Referenzen
    nur relativ zum Objekt ausgedrückt werden, dann würde ja auf einen anderen Speicherbereich gezeigt weden.

    Du kompilierst ja aber auch immer neu? Oder verstehe ich dich falsch? Die Klasse verändert ihre Struktur nicht zur Laufzeit.

    Grüssli



  • @Tachyon: Die Vorwärtsdeklaration habe ich völlig vernachlässigt.
    Und wie mache ich das, wenn es keine Klasse ist, sondern ein typedef? Dann geht das ja so nicht mehr.

    @Dravere: Klar muss ich neu kompilieren.
    wenn ich dann meine Lib erzeugt habe und da drin steht:
    0x0000000 boost:thread_var
    0x0000015 next_var

    Wenn jetzt der Compiler solche Sachen relativ zum Objekt adressieren würde,
    dann würde er bei meiner Applikation next_var an der Stelle 0x00000000 suchen, weil
    die boost:thread_var ja nicht in der Definition stand.

    In diese Richtung ging meine Befürchtung.
    Es hat zwar geklappt, aber ich wußte nicht, ob evtl. durch irgendwelche Compiler-
    Optimierungen und ich mich darauf nicht verlassen kann

    CSpille


  • Administrator

    @CSpille,
    Du weisst aber schon, was ein Präprozessor ist? Das ist eine dumme Textersetzungsmaschine. Und erst wenn der Präprozessor durch ist, geht es an den Kompiler. Wenn du das eine Mal BOOST_THREAD_SUPPORT definiert hast und das andere Mal nicht, dann werden da unterschiedliche Codes an den Kompiler übermittelt. Einmal ist halt die Variable da und das andere Mal nicht. Und solange du dich auf diese Position nicht verlässt, was man normalerweise auch nicht tut, dann passiert da nix. Der Kompiler merkt nicht einmal, dass da mal was hingeschrieben wurde, wenn zum Beispiel BOOST_THREAD_SUPPORT nicht definiert ist.

    Grüssli


Log in to reply