Hallo zusammen, was genau ist der unterschied zwischen Funktionen die entweder static oder inline oder static inline deklariert sind. Irgendwie wird mir da der Zusammenhang nicht so ganz klar. Sieht für mich alles irgendwie gleich aus.
Bezogen auf C: static Funktionen sind nur im betroffenen Modul nutzbar (Scope). inline Funktionen werden evtl. (Compilerentscheidung) an der Stelle des Function-Calls eingefügt, falls dies auf Performance/Platzsicht Sinn macht. Dazu muss die inline-Funktion im selben Source-Modul wie der Function-Call stehen, ansonsten wirds nix. static inline ist halt beides zusammen.
Das einfügen macht der Compiler auch, wenn ich nur static schreibe ohne inline. Lange Frage kurzer Sinn: Ich will Funktionen wie
1 | bool Vergleich(x,y) { |
2 | return x<y; |
3 | }
|
für alle Source Files in meinem Program nutzbar machen, und zwar inline. Im Moment füge ich in die Header Datei
1 | inline static bool Vergleich(x,y) { |
2 | return x<y; |
3 | }
|
ein. Ist das so OK?
Syntaktisch kann man das machen, der Compiler wird nicht meckern. Das static kann du dir an dieser Stelle aber schenken, da es für in Headern definierte Funktionen eigentlich keinen Sinn macht. Das inline-Keyword ist nur ein Hinweis für den Compiler inlining zu betreiben, es ist kein Befehl / keine Anweisung. Aktuelle Compiler sind eigentlich schlau genug solches Optimierungspotential selbst zu entdecken, ich verwende das Keyword deshalb auch nicht. Static verwende ich in meinen Sourcen nur um zu dokumentieren, dass die Funktion nur in einem Source-Modul verwendet wird. So hat ein anderer Programmierer schneller einen Überblick.
Wenn ich static weglasse, meckert der Compiler "../global.h:31: multiple definition of `MQCheckFree_i'".
Ja da mekert wohl der Linker, weil Du die Funktion im Header-File implementiert hast. In jedem Modul in welchem du dieses Header-File includierst, wird eine Kopie dieser Funktion generiert. Solange die Funktion als static definiert ist, ist der Scope nur lokal, dass heisst, es gibt keine Konflikte. Wenn du aber das static weglässt, wird der Scope global und der Linker beschwert sich darüber, dass die Funktion mehrfach vorhanden sei, sobald du das Header-File mehr als nur einmal includiert hast.
http://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Inline.html Eine Funktion, die im .c File als "inline" deklariert wird, mag dort inlined werden oder nicht, ist dort aber in jedem Fall auch als normale Funktion vorhanden, weil der Compiler nicht weiss ob sie anderswo noch verwendet wird (ein Header File ist in C eine reine Textersetzung, keine formale Moduldefinition). Folglich ist es bei "inline" in einem .c File selten sinnvoll, dies ohne "static" zu verwenden, denn bei "static" weiss er dass niemand sonst sie verwenden kann. Wenn du wie hier C-Funktionen inlinen willst, die in mehreren Modulen verwendet werden, und die Definition der Funktion daher in einem .h File unterbringst, dann führt "inline" alleine sofort zum beobachtete Linker-Fehler. Folglich ist dafür entweder "static inline" oder "extern inline" erforderlich. Allerdings steht es dem Compiler frei, eine "inline" Funktion ganz normal zu verwenden, abhängig von Grad der Optimierung (-Os vs. -O3). Wenn er sich dann also gegen inlining entscheidet, gibt es bei "static inline" auch wieder mehr Code als nötig, weil dann die Funktion in jedem Modul dupliziert drinsitzt. Dies wird bei "extern inline" vermieden, wobei man dann aber in einem Modul die Funktion nochmal ohne "extern" definieren muss. Alternativ kann man inlining mit inline void foo (const char) __attribute__((always_inline)); auch unabhängig vom Grad der Optimierung erzwingen.
Beispiel für die extern inline Variante: include.h:
1 | #ifndef INLINE
|
2 | #define INLINE extern inline
|
3 | #endif
|
4 | |
5 | INLINE bool Vergleich(int x, int y) { |
6 | return x<y; |
7 | }
|
main.c:
1 | #define INLINE inline
|
2 | #include "include.h" |
alle anderen *.c:
1 | #include "include.h" |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.