Problem mit circular dependency



  • Ich hab ein Problem.

    Zwei Klassen.h sehen so aus:

    // A.h
    
    #include V.h
    
    class A
    {
    public:
      static void meineMethode();
    };
    
    // V.h
    class A; // forward decl
    
    class V
    {
    public:
      V(A* a);
    
      inline void test() {A::meineMethode();}
    
    };
    

    Ohne die inline void test Methode war die forward decl ja völlig in ordnung, ist ja nur ein Pointer, nun hab ich aber die test Methode, welche auf die statische Methode von A zugreifen muss und demnach müsste ich nun anstatt der forward decl ein #include "A.h" schreiben, was aber dann ne gegenseitige Abhängigkeit schaft.

    Wie umgeht man das problem?



  • Wie umgeht man das problem?

    Mach das inline weg und trenne interface und impl. (header und cpp files...)
    Inline finde ich persönlich eh nicht nötig...
    Simon



  • simon.gysi schrieb:

    Inline finde ich persönlich eh nicht nötig...

    Das ist auch weniger Geschmackssache des Coders als vielmehr Entscheidugssache des Compilers. Ein explizit hingeschriebens inline ist bestenfalls ein Wink mit dem Zaunpfahl - der Compiler kann, muss aber nicht drauf reagieren...



  • pumuckl schrieb:

    simon.gysi schrieb:

    Inline finde ich persönlich eh nicht nötig...

    Das ist auch weniger Geschmackssache des Coders als vielmehr Entscheidugssache des Compilers. Ein explizit hingeschriebens inline ist bestenfalls ein Wink mit dem Zaunpfahl - der Compiler kann, muss aber nicht drauf reagieren...

    Genau. Und wenn ich noch nicht mit der Performance kämpfe, dann lasse ich solche Keywords weg. Wenn der Profiler mit sagt, dass es dort hapert, gebe ich dem Compiler den Wink... :-))

    Simon



  • pumuckl schrieb:

    simon.gysi schrieb:

    Inline finde ich persönlich eh nicht nötig...

    Das ist auch weniger Geschmackssache des Coders als vielmehr Entscheidugssache des Compilers. Ein explizit hingeschriebens inline ist bestenfalls ein Wink mit dem Zaunpfahl - der Compiler kann, muss aber nicht drauf reagieren...

    Eine inline-Funktion muss nicht inline expandiert werden, das ist richtig. Lässt du das inline aber weg, hat der Compiler keine Chance, sie zu inlinen (zumindest nicht in einem traditionellen Übersetzungsmodell).



  • Eine inline-Funktion muss nicht inline expandiert werden, das ist richtig. Lässt du das inline aber weg, hat der Compiler keine Chance, sie zu inlinen (zumindest nicht in einem traditionellen Übersetzungsmodell).

    Ja. Ich weiss.



  • Bashar schrieb:

    Lässt du das inline aber weg, hat der Compiler keine Chance, sie zu inlinen (zumindest nicht in einem traditionellen Übersetzungsmodell).

    Was meinst mit traditionellem Übersetzungsmodell?
    Ich hab hier grad Sutters "Exceptionel C++ Style" vorliegen, dort heißt es

    Your compiler [...] may ignore you, in three interesting ways:
    - By refusing to inline calls to functions that you declared inline
    - By inlining calls to functions you didn't declare inline

    [...] Because you can't write a conforming program that could tell the difference, this falls into the category of perfectly legitimate optimizations that a compiler can (and often should) perform.

    Ich weiß, wenn man aber die Funktionsdefinition von der Deklaration trennt und die Funktion deshalb in ner anderen ÜE landet als der aufrufende Code...

    In particular, functions whose definitions are not put into header files but put into separate modules are commonly thought to be uninlineable [...]
    As far as the compiler goes, they would be correct. While compiling main.cpp, even an inordinately precocious compiler could not possibly peek into the definition of Square(). A precocious linker, however, could. [...] one popular product that supports it [cross-module inlining] totday is MSVC version 7.0 an higher, using /LTCG switch, which stands for "link time code generation"

    Die Diskussion, wann inlining noch stattfinden kann, geht noch weiter, über den Zeitpunkt der Installation über die Laufzeit bis hin zu komplexeren runtime environments (z.B. die Java Virtual Machine), die zu verschiedensten Zeitpunkten inlinen können (z.B.just in time compilation).

    Gut, das geht jetzt weit über "traditionelles Übersetzungsmodell" hinaus, allerdings sind die Traditionen schon was älter, und wir leben in einer modernen Welt ohne Angst vor Neuerungen (zumindest was solche Techniken angeht)



  • Das sollte man alles dazusagen, wenn man behauptet, dass inline unnötig ist. Die Situation ist eben nicht analog zu beispielsweise register, sondern man muss schon den richtigen Compiler nehmen und den entsprechenden Schalter setzen.



  • Mein Fazit aus alledem ist immernoch, inline nicht explizit anzugeben.
    Über Inlining nachzudenken macht erst Sinn, wenn mir der Profiler das sagt - und wenn er mir dann sgat dass es vielleicht was bringen könnte, dann ziehe ich (zur Zeit noch) die Definition aus der .cpp in den Header (ob ich da jetzt inline reinschreibe oder die Definition mitliefere, rekompilieren muss ich eh alles) und überlasse weiterhin dem Compiler die Entscheidung, ob und wo er die Funktion inlined. (Ein inline ofne Definition bringt ja traditionell eh nur innerhalb der ÜE was).
    Später wenn cross-module inlining weiter verbreitet (und ausgefeilt) ist, verzichte ich auch darauf und vertraue der Technik.
    Früher hat ein Entwickler noch selbst entscheiden müssen, welche Variable er in welches Register schiebt, irgendwann haben die Compiler das dann übernommen. Mit dem Inlining ist das nicht anders, wir können nurnoch Entscheidungshilfen bieten auf die eh kaum ein Compiler noch großen Wert legt, bald (vllt. auch jetzt schon) kann mans sich auch ganz abgewöhnen.



  • pumuckl schrieb:

    Mein Fazit aus alledem ist immernoch, inline nicht explizit anzugeben.
    Über Inlining nachzudenken macht erst Sinn, wenn mir der Profiler das sagt - und wenn er mir dann sgat dass es vielleicht was bringen könnte, dann ziehe ich (zur Zeit noch) die Definition aus der .cpp in den Header (ob ich da jetzt inline reinschreibe oder die Definition mitliefere, rekompilieren muss ich eh alles) und überlasse weiterhin dem Compiler die Entscheidung, ob und wo er die Funktion inlined. (Ein inline ofne Definition bringt ja traditionell eh nur innerhalb der ÜE was).
    Später wenn cross-module inlining weiter verbreitet (und ausgefeilt) ist, verzichte ich auch darauf und vertraue der Technik.
    Früher hat ein Entwickler noch selbst entscheiden müssen, welche Variable er in welches Register schiebt, irgendwann haben die Compiler das dann übernommen. Mit dem Inlining ist das nicht anders, wir können nurnoch Entscheidungshilfen bieten auf die eh kaum ein Compiler noch großen Wert legt, bald (vllt. auch jetzt schon) kann mans sich auch ganz abgewöhnen.

    100% ACK.


Anmelden zum Antworten