2009-05-26 10 views
0

Ich habe mich immer gefragt, ob es gut oder schlecht ist, triviale Methode zweimal zu definieren, je nachdem
wenn das Projekt auf debug/Release -State ist. Dies dient dazu, sie zu verlinken. Zum Beispiel foo.h:Ist es gut, trivial inlined-Methoden zweimal basierend auf Debug/Release-Status des Projekts zu definieren?


class Foo 
{ 
     public: 
       ... 

       const bool& IsBoolean() const; 

     private: 
       bool _boolean; 
}; 

#ifndef _DEBUG 

/** We're in release, so let's advice compiler to inline this... 
    * 
    * 
    */ 

inline const bool& Foo::IsBoolean() const 
{ 
     return _boolean; 
} 

#endif 

Und jetzt, in foo.cpp:


#include "Foo.h" 

... 

#ifdef _DEBUG 

/** We're debugging this, no need for inlining... 
    * 
    * 
    */ 

const bool& Foo::IsBoolean() const 
{ 
     return _boolean; 
} 

#endif 

Ist das völlig nutzlos? Zum Beispiel aufgrund der Fähigkeit des Compilers (MSVC) Methoden selbst zu inline/optimieren?

Nichtsdestotrotz benutze ich das seit Jahren. Bitte korrigieren Sie mich, wenn ich hier völlig falsch liege ...

Antwort

9

Es ist Zeitverschwendung, aus verschiedenen Gründen.

Das Inline-Schlüsselwort ist ein Hinweis, den der Compiler nach Belieben ignorieren kann. Genauso wie es kostenlos inline ist, auch wenn das Schlüsselwort nicht angegeben ist. Also, ob Sie es hinzufügen, wird wahrscheinlich nichts für den Compiler ändern

Darüber hinaus sind alle Funktionen innerhalb der Klassendefinition implizit inlined definiert. Aus diesem Grund werden kurze Funktionen wie Getter und Setter fast immer innerhalb der Klassendefinition definiert.

Als nächstes, wenn Sie eine Funktion als Inline markieren möchten, gibt es keinen Grund, dies auch nicht in Debug-Builds zu tun.

Das Schlüsselwort inline hat fast nichts mit dem Compiler zu tun, der tatsächlich Funktionen inliniert. Sie sind getrennte Konzepte. Eine vom Programmierer mit inline markierte Funktion bedeutet, dass der Linker sich keine Sorgen machen sollte, wenn er mehrere identische Definitionen sieht. Dies geschieht normalerweise, wenn die Funktion in einem Header definiert ist, der in mehrere Kompilierungseinheiten eingeschlossen wird. Wenn die Funktion inline markiert ist, führt der Linker die Definitionen zusammen. Wenn nicht, erhalten Sie einen Fehler. Mit anderen Worten verursacht das Hinzufügen und Entfernen dieses Schlüsselwortes Compilerfehler. Das ist wahrscheinlich nicht das, was du willst.Der einzige Grund, warum es ein bisschen Überlappung zwischen dem Schlüsselwort C++ inline und der Compiler-Optimierung gibt, ist, dass wenn eine Funktion mit inline markiert ist, es sicher in jeder Kompilierungseinheit enthalten ist, was bedeutet, dass die Definition immer sein wird sichtbar, wenn die Funktion aufgerufen wird. Und das macht es easire für den Compiler, um Aufrufe an die Funktion zu inline.

Schließlich ist Inlining nicht immer eine Leistungsverbesserung. Es ist leicht, eine Situation zu schaffen, in der Inlining nicht mehr als die Code-Größe zum Explodieren bringt, mehr Cache-Fehler verursacht und insgesamt den Code verlangsamt. Das ist einer der Gründe, warum inline (bestenfalls) vom Optimierer als Hinweis behandelt wird. Im schlimmsten Fall wird es vollständig ignoriert.

Also was Sie tun, wird 1) verursachen Compilerfehler im Debug-Modus, die nicht in Release-Builds vorhanden war, und 2) haben keinen Einfluss auf die Leistung.

+0

Gut genug, Sie haben das perfekt erklärt. Seufzend, das bedeutet eine riesige Codebereinigung :(Aber, danke! – nhaa123

+1

Nun, das Löschen einer Menge von doppeltem Code ist nicht die schlimmste Form der Bereinigung gibt es, zumindest.;) – jalf

1

Wiederholung ist schlecht. Selbst wenn Sie mit einem hirntoten Compiler arbeiten, können Sie diese Wiederholung im schlimmsten Fall vermeiden, indem Sie ein Makro INLINEan einer Stelle entweder inline oder nichts verwenden.

2

Sieht wie eine Verschwendung von Speicherplatz und eine unnötige Code-Duplizierung aus. Normalerweise ist der Compiler sehr gut in der Lage, eigenständig zu bestimmen, welche Funktionen inline sind und welche nicht. Noch mehr, wenn Sie MSVC verwenden, die den /LTCG (Link Time Code Generation) Schalter hat, bedeutet dies, dass Ihre trivialen Methoden inline werden, auch wenn sie in der cpp sind.

1

Die einfachste Sache zu tun, was Sie wollen, ist den Code in eine eigene Datei filename.inl setzen und dann die Datei entweder in den Header oder die Quelldatei bedingt enthalten. Sie sollten auch die Funktionen in der Datei .inl mit einem bedingten Makro voranstellen, das auf inline erweitert wird, wenn die Datei in der Kopfzeile und ansonsten in einem leeren Makro enthalten ist.