Inline verhindern ?
-
Folgender Beispielcode:
// person.hpp #include <string> class Person { public: const std::string& getName() const; private: // nehmen wir mal an, diese Membervariable wär mit dem // pimpl-Idiom gesetzt worde, zur Einfachheit lass ich // das aber weg .. std::string name; };
// person.cpp const std::string& Person::getName() const { return name; }
// foo.cpp #include <iostream> using namespace std; void foo(const Person& person) { cout << person.getName() << endl; }
Jetzt könnte es ja sein, das ich einen vernünftigen Compiler verwende
und der das inlined, soweit ich weiß, würde foo dann folgendermaßen
aussehen:void foo(const Person& person) { cout << person.name << endl; }
Stimmt das so? Wenn ja, wie kann ich verhindern, dass er automatisch inlined.
Immerhin würde ich damit den Benutzer ständig dazu zwingen seine Object Files
neu zu kompilieren, wenn ich eine Membervariable entferne oder die getter und
setter irgendwie modifizere. Darum auch der Kommentar wegen dem pimpl-Idiom.Als Compiler nehmen wir einfach mal einen gcc 3.4.* an,
idealerweise auch Visual C++ 7.1 oder 8.0 Beta.Danke
-
Das darf ein Compiler IMO nicht inlinen. Es muss bei Optimierungen gesichert sein, dass die Semantik der Sprache erhalten bleibt.
EDIT: Aber guter Punkt für meine in der Entstehung begriffene inline-FAQ. Es soll ja Compiler geben, die auch ohne sichtbare Definition inlinen können (Intel?), wie gehen die mit dem Problem um?
-
Bei den Compilern, die das können, sind die Objektdateien keine Objektdateien im herkömmlichen Sinne, sondern eher Bytecode in einer Intermediate Language.
Beim Linken wird dann der Optimizer auf den ganzen Code angeschmissen, so dass er Funktionen inlinen kann, die vorher durch die räumliche Trennung nicht geinlined werden konnten.
-
Da sich Person::getName() in einer anderen Übersetzungseinheit befindet ist sichergestellt, dass der gcc das nicht inlinen kann. Dies ist bei allen Compilern so, die ich kenne.
-
Bei Compilern ja, der MSVC-Linker hingegen kanns trotzdem noch inlinen (soweit ich die Doku verstanden habe, benutzt habe ich es nie).
-
operator void schrieb:
Bei Compilern ja, der MSVC-Linker hingegen kanns trotzdem noch inlinen (soweit ich die Doku verstanden habe, benutzt habe ich es nie).
Jo, hier uebernimmt der Linker die komplexe Aufgabe der Optimierung.
Der Compiler erstellt nur Bytecode. Der Linker kennt dann den ganzen Code und kann natuerlich alles inlinen. Da kann er natuerlich noch ein paar andere nette optimierungen machen.
-
Und wenn wir einen (sehr) dummen kompiler haben, sollten doch die 2 Zeilen
static int dummy;
++dummy; //damit ers nicht wegoptimiert...
weiterhelfen, imho?
-
ness: Mach die Funktion lieber virtual.
-
Als Compiler nehmen wir einfach mal einen gcc 3.4.* an,
__attribute__((noinline))
-
ness schrieb:
Und wenn wir einen (sehr) dummen kompiler haben
Dann tun wir ihn in die Tonne, wo er hingehört.