Forum: Compiler & IDEs Funktiondekleration static, inline oder inline static?


von Be M. (bemi)


Lesenswert?

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.

von Alexander (Gast)


Lesenswert?

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.

von Be M. (bemi)


Lesenswert?

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?

von Alexander (Gast)


Lesenswert?

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.

von Be M. (bemi)


Lesenswert?

Wenn ich static weglasse, meckert der Compiler
"../global.h:31: multiple definition of `MQCheckFree_i'".

von Peter (Gast)


Lesenswert?

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.

von Andreas K. (a-k)


Lesenswert?

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.

von Andreas K. (a-k)


Lesenswert?

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
Noch kein Account? Hier anmelden.