#define



  • Hallo,
    ich hoffe mein Beitrag ist richtig platziert 🙂
    ich habe ein "Verständnis" 😕 Problem und bitte um Hilfe:

    //Switch Interface Switch.hpp
    void fkt(void);
    
    #if (#define (A))
    	#import "A.hpp"
    #else if (#define (B))
    	#import "B.hpp"
    #endif()
    
    //Switch Impl. Switch.cpp
    #import "Switch.hpp"
    
    void fkt(void){
    
    #if (#define (A))
    	fkt_A();
    #else if (#define (B))
    	fkt_B();
    #endif()
    }
    
    //A.hpp
    void fkt_A(void);
    
    //A.cpp
    #import "A.hpp"
    void fkt_A(){
    printf("fkt_A");
    }
    
    //B.hpp
    void fkt_B(void);
    
    //B.cpp
    #import "B.hpp"
    void fkt_B(){
    	printf("fkt_B");
    }
    
    //main
    #import "Switch.hpp"
    
    #ifndef A
    #define A
    #endif
    
    int main(int argc, char **argv){
    	fkt();
    	return 0;
    }
    

    1. warum ist die Ausgabe immer "fkt_B" egal was in "define" steht?
    2. wie konnte man "Switch" so elegant machen, so dass nicht zweimal die Abfrage #if.. (einmal in switch.hpp und in switch.cpp) vorkommt?

    vielen Dank



  • lampda schrieb:

    #if (#define (A)) 
    #endif()
    #import "Switch.hpp"
    

    Wo hast du denn den Käse her??
    Dir ist klar, dass es hier im Forum um C++ geht? Das was du da schreibst, hat zwar entfernte Ähnlichkeit mit C++-Präprozessor-Befehlen, aber eben nur entfernt.

    Ein aktuelles Buch deiner Wahl sollte da weiterhelfen.


  • Mod

    pumuckl schrieb:

    Dir ist klar, dass es hier im Forum um C++ geht? Das was du da schreibst, hat zwar entfernte Ähnlichkeit mit C++-Präprozessor-Befehlen, aber eben nur entfernt.

    Das sind, wenn mich mein Blick nicht trügt, Erweiterungen des Präprozessors für den GNU Compiler. Frag mich aber nicht, was die genau machen. Sie sind übrigens schon allesamt lange deprecated.



  • Präprozessor Direktiven werden einmal beim Parsen ausgewertet.
    Dabei wird das Programm sequentiell von oben nach unten gelesen. (#include wird halt dazwischen 'eingefügt')
    Zu dem Zeitpunkt wo du zu Zeile 4 kommst, ist A nicht definiert.

    Siehe auch folgendes kurzes Beispiel:

    //#define A
    
    #ifdef A
            #error A
    #else
            #error B
    #endif
    
    #define A
    

    Wenn du es davor definest, dann kriegst error A, sonst B

    Gruß,
    XSpille



  • XSpille schrieb:

    Präprozessor Direktiven werden einmal beim Parsen ausgewertet.
    Dabei wird das Programm sequentiell von oben nach unten gelesen. (#include wird halt dazwischen 'eingefügt')
    Zu dem Zeitpunkt wo du zu Zeile 4 kommst, ist A nicht definiert.

    Siehe auch folgendes kurzes Beispiel:

    //#define A
    
    #ifdef A
            #error A
    #else
            #error B
    #endif
    
    #define A
    

    Wenn du es davor definest, dann kriegst error A, sonst B

    Gruß,
    XSpille

    vielen Dank für Eure Hilfe.
    es funktioniert nur wenn #define A in Switch.hpp platziert ist, aber das ist nicht was ich vor habe. Ich möchte #define von aussen für Switch.hpp setzen..
    (Switch.hpp/cpp soll später nach black-Box-prinzip behandelt werden)

    das hat mit dem Parser nicht zu tun, da der Code nicht wie im Beitrag aussieht, sondern es sind eigenständige "klassen".

    ich dachte der übersetzer fängt bei main an und da ist #define A gesetzt, aber irgendwie verliert er diese wenn er bei Switch.hpp ist. Warum?
    ist das Problem, dass: main kennt Switch.hpp aber nicht umgekehrt. wie kann ich das lösen ohne circle-effekt?



  • Ich habe mir das da oben nicht angetan, aber hilft dir nicht einfach:

    #ifndef MY_HPP
    #define MY_HPP
    
    // ..
    
    #endif
    

  • Mod

    Vielleicht wäre eher dies etwas für dich:
    http://en.wikipedia.org/wiki/Policy-based_design



  • Du solltest #define besser nur in der Schreibweise einer Textersetzung verwenden, so dass vom Präprozessor eindeutig vorbereitete Sourcetexte zum Compilieren angesprochen sind. Es wird dann die Variante A oder B compiliert - nützlich z.B. zur Unterscheidung einer Testversion von einer Releaseversion. Während der Laufzeit mit switch lassen sich nur zuvor auch compilierte Varianten - etwa von Funktionen - auswählen.

    Vielleicht erläuterst du einmal genauer, wozu das ganze dienen soll.



  • lampda schrieb:

    ...

    Entwickelst du auf Mac OS X?



  • berniebutt schrieb:

    Du solltest #define besser nur in der Schreibweise einer Textersetzung verwenden, so dass vom Präprozessor eindeutig vorbereitete Sourcetexte zum Compilieren angesprochen sind. Es wird dann die Variante A oder B compiliert - nützlich z.B. zur Unterscheidung einer Testversion von einer Releaseversion. Während der Laufzeit mit switch lassen sich nur zuvor auch compilierte Varianten - etwa von Funktionen - auswählen.

    Vielleicht erläuterst du einmal genauer, wozu das ganze dienen soll.

    vielen Dank!
    irgendwie kriege ich die kurve nicht hin 😡 das ist auch nicht mein Stärkebereich..

    Du hast es erkannt. Ich möchte eine Rückwärtse-kompatibiltät zweier Programm-versionen (,die Plattform abhängig sind..) realiesieren. Der Plan war bzw. ist zur Laufzeit zu erkennen oder auch beim Projekterstellen die geeignete Funktion aus der passenden Version zu includieren..

    ich muss zugeben mein Vorgehensweise ist nicht gerade die beste, aber leider fehlt mir da auch die nötige Kreativität.



  • Zeus schrieb:

    lampda schrieb:

    ...

    Entwickelst du auf Mac OS X?

    das darf keine Rolle spielen. aber ja


  • Mod

    Kanns sein, dass du so etwas suchst?

    switch.hpp:

    #include "config.hpp"
    #include "A.hpp"
    #include "B.hpp"
    #include "C.hpp"
    
    void foo()
    {
    #ifdef WINDOWS
     a();
    #elif defined(LINUX)
     b();
    #elif defined(MACOS)
     c();
    #endif
    }
    

    config.hpp

    // Hier eventuell für den Compiler anspassen 
    // oder per Compileroption übergeben 
    // oder für alle gängigen Compiler umschreiben
    
    #ifdef _WIN32
     #define WINDOWS
    #elif defined(__linux)
     #define LINUX
    #elif defined (__MACH__)
     #define MACOS
    #endif
    


  • Wenn ich das richtig verstehe, brauchst du nach OS zu unterscheidende Funktionen und möchtest alles aus möglichst einem Projekt machen. Der Ansatz ist schon mal gut. Vorschlag: Separiere die Funktionen nach OS und bilde eigenständige LIBs oder DLLs. Dann lässt sich mit #define, etc. die Einbindung in die jeweilge OS-Version übersichtlich konzentrieren.



  • vielen Dank für Eure Hilfe!
    Problem wurde gelöst in dem ich ein extra headerDatei mit den ganzen define's erstellt, und diese in Switch importiert. und damit ist der circle-effekt umgegangen. hoffe hilft das jemanden weiter .


Log in to reply