Das Schlüsselwort inline
-
seldon schrieb:
Generell ist die Erwartungshaltung, dass eine inline-Funktion inline verwendet wird, aber vernünftig.

-
Den früheren Compilern musste man eben noch sagen, welche Funktionen sie am besten inlinen. Genauso wie man ihnen mit
registersagen musste, welche Variablen in ein Register sollen. Heutige Compiler wissen so etwas besser, beide Schlüsselwörter sind nur noch Hinweise, dem Compiler ist es egal, ob vor einer Funktioninlinesteht oder nicht, er entscheidet selbst, was er tut.
registerist mittlerweile deprecated,inlinenicht, weil es auch noch Einfluss auf die ODR hat (und damit möglicherweise Inlining erleichtert).
-
Der Compiler muss nicht inlinen, wenn inline davor steht. Er darf dafür inlinen, wenn kein inline davor steht.
Der Guru schreibt zum Thema: http://www.gotw.ca/gotw/033.htm
-
Und hier noch die Inline FAQ:
http://www.c-plusplus.net/forum/105893
-
Wieso hat man inline 2 Bedeutungen gegeben? Was, wenn ich eien Funktion in einen Header schreiben möchte, aber nicht will, dass sie geinlined wird?
-
Weil beide Bedeutungen miteinander zu tun haben. Warum solltest du die Funktion in den Header schreiben wollen, wenn du sie nicht inlinen lassen willst? Die ODR-Ausnahme hat direkt mit dem Inlinen zu tun, denn nur wenn die Funktion im Header steht, sieht der Compiler den Code und kann sie auch in anderen UE inlinen. Willst du sie nicht inlinen, kannst du sie auch in die CPP-Datei packen, wo sie hingehört.
-
Wenn ich eine Library schreibe, möchte ich Header-only bleiben. Da kann ich das inlining nicht verhindern.
-
314159265358979 schrieb:
Wenn ich eine Library schreibe, möchte ich Header-only bleiben. Da kann ich das inlining nicht verhindern.
Dafür war
inlineaber nie gedacht. Die zweite Bedeutung kommt davon, dass du etwas machst, wofür es nicht gedacht war.Grüssli
-
Wie soll ich inline denn verwenden?
-
314159265358979 schrieb:
Wieso hat man inline 2 Bedeutungen gegeben? Was, wenn ich eien Funktion in einen Header schreiben möchte, aber nicht will, dass sie geinlined wird?
Weil das "inlinen" eine unbeobachtbare Optimierung des Compilers ist. Der Standard schreibt nur das Verhalten einer abstrakten Maschine vor und fordert, dass das beobachtbare Verhalten einer realen Implementierung dem der abstrakten Maschine entspricht. Er kann also prinzipiell nicht festlegen, wann eine Funktion geinlinet wird.
Es gibt aber Implementierungen, die Funktionen nur dann inlinen können, wenn ihr Funktionskörper an der Aufrufstelle sichtbar ist. (Eigentlich sollten das sogar die meisten sein, weil die Alternative mit dem Übersetzungsmodell von C++ schwer zusammenpasst. Dazu muss man im Prinzip nachträglich in den bereits compilierten Übersetzungseinheiten Code einfügen, das heißt, das traditionelle Schema von Compiler, den Quelltext zu Objektcode übersetzt, und Linker, der die Objektcodefiles und Libraries zusammenbindet, aufbrechen. Bei MS nennt sich das Link-Time Code Generation.)
Und das kann man als Programmierer nicht umsetzen, ohne die ODR zu verletzen. Deshalb kann man Memberfunktionen im Klassenrumpf definieren oder das Schlüsselwort inline benutzen, um die ODR zu umgehen (und damit inlining zu ermöglichen).
-
314159265358979 schrieb:
Oftmals heißt es, inline sei für "Funktionsinling" da.
Stimmt ja auch.
314159265358979 schrieb:
Ich dachte bisher dass es sich durchgesetzt hat, dass jeder weiß, dass das falsch ist und inline für freie Funktionen in Headern gebraucht wird.
Das eine schließt das andere nicht aus.
314159265358979 schrieb:
Nun habe ich in Struppis "The C++ Programming Language" gelesen, dass er ebenfalls von Funktionsinlining spricht. Was ist nun richtig? Ich bin verwirrt.
Also...
es gibt inline Funktionen und es gibt Funktionen, die keine inline Funktionen sind. Das kann man durch das Schlüsselwort "inline" steuern aber auch dadurch, dass man eine Funktion innerhalb einer struct/class Definition definiert. Zwischen Inline-Funktionen und nicht-inline-Funktionen werden in der ODR (one definition rule) unterschieden. Beispielsweise muss eine Definition einer inline-Funktion in der aktuellen Übersetzungseinheit vorhanden sein, damit sie benutzbar wird. Eine Deklaration reicht da nicht aus. Dass eine Definition in der aktuellen ÜE vorhanden sein muss, erleichtert natürlich das tatsächliche Inlining. Die ODR macht auch die Ausnahme, dass es Programm-weit mehrere aber identische Definitionen einer Inlinefunktion geben darf. Das ist gut so, weil Du damit eine Definition in eine Header-Datei schreiben darfst, die dann mehrfach in versch ÜEs inkludiert wird. Natürlich darf der Compiler auch nicht-inline-Funktionen "inlinen" oder das Inlining von inline-Funktionen unterlassen. Wenn man sonst nicht undefiniertes Verhalten hervorruft, dürfte man hier auch keinen Unterschied merken (außer vielleicht bei der Performance). Die "InlinING-Optimierung" fällt under die "as-if"-Regel.Zusammenfassung:
- Es gibt unterschiedliche Regeln für inline/non-inline Funktionen (siehe ODR)
- Die Regeln für inline Funktionen machen das tatsächliche Inlining einfacher, da für das Inlining von Funktionen, die in anderen ÜEs definiert werden, LTO (link time optimization) erforderlich wäre. LTO ist aber wenig verbreitet / wird kaum benutzt.Wenn Du also dem Compiler die Gelegenheit geben willst, eine Funktion zu "inlinen", die in mehreren ÜEs verwendet wird, dann definierst Du sie einfach in einem Header und machst eine inline-Funktion draus.
Du kannst natürlich auch "inline" missbrauchen und hoffen, dass der Compiler inline-Funktionen nur dann "inlinet", wenn es sich auch lohnt. Um das zu beurteilen verwenden moderne Compiler Heuristiken. Es gibt aber möglicherweise auch "unmoderne" Compiler, die das mit der inline-Eigenschaft einer Funktion ernst nehmen und sich verpflichtet fühlen, das Inlining wirklich durchzuführen. Ich glaube, LCC-WIN ist so einer. Der frisst aber eh nur reines C. Sicher bin ich mir da jetzt aber nicht.
-
krümelkacker schrieb:
Du kannst natürlich auch "inline" missbrauchen und hoffen, dass der Compiler inline-Funktionen nur dann "inlinet", wenn es sich auch lohnt. Um das zu beurteilen verwenden moderne Compiler Heuristiken.
Wieso ist das ein Missbrauch? Natürlich hofft man, dass der Compiler eine möglichst optimale Entscheidung bezüglich Inline ja oder nein trifft.
Es gibt aber möglicherweise auch "unmoderne" Compiler, die das mit der inline-Eigenschaft einer Funktion ernst nehmen und sich verpflichtet fühlen, das Inlining wirklich durchzuführen. Ich glaube, LCC-WIN ist so einer. Der frisst aber eh nur reines C. Sicher bin ich mir da jetzt aber nicht.
Ich auch nicht, aber inline in C ist ja nochmal eine ganz andere Baustelle. Da funktioniert die ODR auch ein bisschen anders, und mit inline kann man ziemlich auf die Nase fallen, wenn man glaubt, dass das wie in C++ funktioniert.
-
314159265358979 schrieb:
Wieso hat man inline 2 Bedeutungen gegeben? Was, wenn ich eien Funktion in einen Header schreiben möchte, aber nicht will, dass sie geinlined wird?
Dann packst du sie in einen anonymen Namespace. Voilá, internal linkage.
-
Bashar schrieb:
krümelkacker schrieb:
Du kannst natürlich auch "inline" missbrauchen und hoffen, dass der Compiler inline-Funktionen nur dann "inlinet", wenn es sich auch lohnt. Um das zu beurteilen verwenden moderne Compiler Heuristiken.
Wieso ist das ein Missbrauch?
Missbrauch ist vielleicht nicht das richtige Wort hier. Aber ja, das Schlüsselwort heißt "inline" und nicht "multidefok" (für "multiple definitions are ok") oder so'was. Dem Schlüsselwort "inline" kann man die Intention schon ansehen, nämlich: Die inline-Regeln sind dazu da, das Inlining einer Funktion, die in mehreren ÜEs verwendet wird, drastisch zu begünstigen -- ohne dass man dafür so etwas wie LTO braucht.
pumuckl schrieb:
Dann packst du sie in einen anonymen Namespace. Voilá, internal linkage.
Das würde ich nicht machen. Wird der Header in 10 ÜEs eingebunden und genutzt, gibt es auch 10 Exemplare dieser Funktionen (mit verschiedenen Adressen), die aber alle das gleiche tun.
-
krümelkacker schrieb:
Das würde ich nicht machen. Wird der Header in 10 ÜEs eingebunden und genutzt, gibt es auch 10 Exemplare dieser Funktionen (mit verschiedenen Adressen), die aber alle das gleiche tun.
Einen Tod muss er sterben. Entweder explizit external linkage durch Deklaration im header und Definition im .cpp (selbst das können findige Linker noch inlinen1). Oder inline deklariert und dadurch internal linkage (plus external linkage version, wenn die Adresse der inline Funktion irgendwo geholt wird). Oder reine internal linkage und dann eine Version in jeder ÜE. Letztere kann der Compiler oder Linker rauswerfen, wenn sie nicht benutzt wird.
Davon abgesehen:
1: Ja, auch Linker können inlinen, wenn sie wollen. Womit ipsec widersprochen ist, und vor allem:
314159265358979 schrieb:
Was, wenn ich eien Funktion in einen Header schreiben möchte, aber nicht will, dass sie geinlined wird?
Wenn man partout nicht will, dass eine Funktion geinlined wird, dann muss man sich anstrengen, und zwar richtig. Wobe es aber natürlich keinen Grund gibt, es nicht zu wollen.