Inline-Optimierung durch Klassenunbekanntheit bei Deklaration unterbunden?



  • Für myGame?



  • Nexus schrieb:

    ...die Entwickler haben sinnlos viele Header eingebunden, wo eine Vorwärtsdeklaration gereicht hätte. Von Pimpl und so keine Spur... 🙄

    Kann der Compiler Pimpl wegoptimieren und alles inlinen? Sonst geht das mal garnicht!!!!!1efl



  • Eine Vorwärtsdeklaration ist nur dann ausreichend, wenn es unerheblich ist, ob der Compiler Informationen über den Typ hat oder nicht. Und wenn der Compiler diese Informationen benötigt, ist LTO aus dem Rennen. LTO ist dazu da Optimierungen vorzunehmen, die der Compiler nicht vornehmen kann. Zum Beispiel:

    In classA.h wird eine Klasse mit der als inline deklarierten Funktion funcFromA() deklariert.
    In classA.cpp steht die Definition der Klasse aus classA.h, inklusive besagter funcFromA()
    In classB.h wird classA.h inkludiert. Bei jeder Verwendung von funcFromA() in dieser Datei wird das inline geflissentlich ignoriert. Warum? Weil der Compiler an dieser Stelle die Definition nicht kennt.
    LTO soll nun diese Definitionen über die Objektdateigrenzen hinaus transportieren, um doch noch ein Inlining zu ermöglichen.

    Zweites Beispiel:
    Die Klasse A enthält als Member einen Zeiger auf eine Instanz von Klasse B. Muss die Headerdatei mit der Deklaration von Klasse B inkludiert werden? Nein. Eine Vorwärtsdeklaration reicht. Handelt es sich aber nicht um einen Zeiger, sondern eine Instanz, reicht eine Vorwärtsdeklaration nicht.

    Zum zweiten Beispiel sei zu sagen, dass es als "schick" gilt, Zeiger auf komplexe Datenstrukturen zu verwenden, die dann nur eine Vorwärtsdeklaration benötigen, und so, vermeintlich, die Kompilierungszeit verringern. Das ist dann Teil des pImpl -Idioms (Pointer to Implementation) und ist ganz supi l33t. Und erzeugt eine Flut von zusätzlicher Tipparbeit, die eine Flut von zusätzlichen potentiellen Fehlern mit sich führt. Ein geschickter Modularer Aufbau der Quelldateien ist meist effizienter um Kompilierungszyklen zu verkürzen. Aber wie bei Allem ist das immer in Relation zum Projekt zu sehen. Eine allgemeingültige Aussage wird es da wohl niemals geben.



  • Yamakuzure schrieb:

    In classA.h wird eine Klasse mit der als inline deklarierten Funktion funcFromA() deklariert.
    In classA.cpp steht die Definition der Klasse aus classA.h, inklusive besagter funcFromA()
    In classB.h wird classA.h inkludiert. Bei jeder Verwendung von funcFromA() in dieser Datei wird das inline geflissentlich ignoriert. Warum? Weil der Compiler an dieser Stelle die Definition nicht kennt.

    Warum soll er die Definition nicht kennen, wenn "classB.h" den Header "classA.h" mit der Inline-Funktion inkludiert?



  • Na ja, er kennt die Funktionsdeklaration aber die Funktionsdefinition ist ja in der .cpp-Datei, oder?



  • Eisflamme schrieb:

    Na ja, er kennt die Funktionsdeklaration aber die Funktionsdefinition ist ja in der .cpp-Datei, oder?

    Nein, Yamakuzure sprach von einer Inline-Funktion.



  • Ja, aber er hat trotzdem diese im Header deklariert und in der Quellcodedatei definiert, falls so was geht:

    In classA.h wird eine Klasse mit der als inline deklarierten Funktion funcFromA() deklariert. 
    In classA.cpp steht die Definition der Klasse aus classA.h, inklusive besagter funcFromA()
    

    Ich benutze inline eh nie, daher hab ich keine Ahnung.



  • Der Witz von inline ist ja gerade, dass du Funktionen im Header definieren kannst. inline -Deklarationen sind zwar erlaubt, aber dann muss die Funktionsdefinition in der selben Übersetzungseinheit wie der Aufruf vorhanden sein. Das läuft also darauf hinaus, die Definition im Header anzugeben, wenn man Linkerfehler vermeiden möchte.

    Yamakuzure hat sich auch sonst etwas unklar ausgedrückt. Wenn im Header nur die Klassendeklaration steht, kann er dort auch keine Methode deklarieren. Falls er hingegen wirklich die ganze Klasse erst in der .cpp-Datei definiert, kann er deren Methoden nicht in anderen Headern – hier "classB.h" – benutzen.



  • Yamakuzure schrieb:

    [...] Zum Beispiel:

    In classA.h wird eine Klasse mit der als inline deklarierten Funktion funcFromA() deklariert.
    In classA.cpp steht die Definition der Klasse aus classA.h, inklusive besagter funcFromA()
    In classB.h wird classA.h inkludiert. Bei jeder Verwendung von funcFromA() in dieser Datei wird das inline geflissentlich ignoriert.

    Stopp mal. Das ist gar nicht erlaubt. Du darfst in einer Übersetzungeinheit keine Inline-Funktion benutzen, die nur deklariert wurde. Also
    ÜE1:

    inline int foo(int);
    
    int bar(int x)
    {
      return foo(x*2);
    }
    

    ÜE2:

    inline int foo(int x) {return x;}
    
    int bar(int);
    
    int main()
    {
      return bar(0);
    }
    

    ist kein gültiges Programm. Der Compiler wird sich vielleicht nicht beschweren, aber der Linker wird wahrscheinlich meckern; denn in ÜE1 wird die inline-Funktion benutzt aber nur deklariert. In ÜE2 wird sie definiert, aber nie benutzt. Weil die Funktion in ÜE2 nicht benutzt wird und die ODR fordert, dass jede Benutzung eine Definition in derselben ÜE erfordert, darf ein Compiler beim Übersetzen von ÜE2 die Definition der inline-Funktion aussparen. ==> Der Linker wird dann wegen eines unaufgelösten Symbols meckern.

    Siehe 3.2/3 [one definition rule]:

    ... An inline function shall be defined in every translation unit in which it is used.

    Das Schlüsselwort "inline" wird scheinbar öfters missverstanden. Es ist primär dazu da, einem Compiler, das tatsächliche "Inlining" leichter zu machen, indem in jeder ÜE, in der die Inline-Funktion benutzt wird, auch die entsprechende Definition vorhanden ist (so will es die ODR).

    Nexus schrieb:

    Der Witz von inline ist ja gerade, dass du Funktionen im Header definieren kannst.

    ...sogar definieren musst. Denn ohne Definition in der aktuellen ÜE darf die Funktion nicht benutzt werden.

    Edit: Sorry Nexus. Hatte ich komplett übersehen, dass Du auch darauf aufmerksam gemacht hattest.

    Gruß,
    kk



  • krümelkacker schrieb:

    Nexus schrieb:

    Der Witz von inline ist ja gerade, dass du Funktionen im Header definieren kannst.

    ...sogar definieren musst. Denn ohne Definition in der aktuellen ÜE darf die Funktion nicht benutzt werden.

    Man muss nicht, aber es macht keinen Spaß, in jeder cpp, in der man die Funktion braucht, die Definition zu wiederholen 😉



  • Michael E. schrieb:

    krümelkacker schrieb:

    Nexus schrieb:

    Der Witz von inline ist ja gerade, dass du Funktionen im Header definieren kannst.

    ...sogar definieren musst. Denn ohne Definition in der aktuellen ÜE darf die Funktion nicht benutzt werden.

    Man muss nicht, aber es macht keinen Spaß, in jeder cpp, in der man die Funktion braucht, die Definition zu wiederholen 😉

    ...oder einen zweiten Header einzufügen, der dann schließlich die Definition enthält. Das ist natürlich beides eher sinnfrei. Ich hätte für alle anderen Korintenkacker die Aussage noch eingrenzen müssen. 🙂


Anmelden zum Antworten