inline function specifier
Deklariert eine inline function .
Inhaltsverzeichnis |
Syntax
| inline Funktionsdeklaration | (seit C99) | ||||||||
Erklärung
Die Absicht des
inline
-Spezifizierers ist es, als Hinweis für den Compiler zu dienen, um Optimierungen durchzuführen, wie z.B.
Function Inlining
, die normalerweise erfordern, dass die Definition einer Funktion an der Aufrufstelle sichtbar ist. Compiler können (und tun dies in der Regel) das Vorhandensein oder Fehlen des
inline
-Spezifizierers für Optimierungszwecke ignorieren.
Wenn der Compiler Funktionsinlining durchführt, ersetzt er einen Aufruf dieser Funktion durch ihren Körper, wodurch der Overhead eines Funktionsaufrufs vermieden wird (das Ablegen von Daten auf dem Stack und das Abrufen des Ergebnisses). Dies kann zu einer größeren ausführbaren Datei führen, da der Code für die Funktion mehrfach wiederholt werden muss. Das Ergebnis ähnelt funktionsähnlichen Makros , mit der Ausnahme, dass Bezeichner und Makros, die in der Funktion verwendet werden, sich auf die Definitionen beziehen, die zum Zeitpunkt der Definition sichtbar sind, nicht zum Zeitpunkt des Aufrufs.
Unabhängig davon, ob Inlining stattfindet, sind die folgenden Semantiken von Inline-Funktionen garantiert:
Jede Funktion mit interner Verknüpfung kann ohne weitere Einschränkungen als
static inline
deklariert werden.
Eine nicht-statische Inline-Funktion kann kein nicht-konstantes statisches Funktionslokales definieren und kann nicht auf ein statisches File-Scope-Element verweisen.
static int x; inline void f(void) { static int n = 1; // Fehler: nicht-konstante static-Variable in einer nicht-statischen inline-Funktion int k = x; // Fehler: nicht-statische inline-Funktion greift auf eine static-Variable zu }
Wenn eine nicht-statische Funktion als
inline
deklariert wird, muss sie in derselben Übersetzungseinheit definiert werden. Die Inline-Definition, die nicht
extern
verwendet, ist nicht extern sichtbar und verhindert nicht, dass andere Übersetzungseinheiten dieselbe Funktion definieren. Dies macht das
inline
Schlüsselwort zu einer Alternative zu
static
für die Definition von Funktionen in Header-Dateien, die in mehrere Übersetzungseinheiten desselben Programms eingebunden werden können.
Wenn eine Funktion in einigen Übersetzungseinheiten als
inline
deklariert wird, muss sie nicht überall als
inline
deklariert werden: höchstens eine Übersetzungseinheit kann auch eine reguläre, nicht-inline nicht-statische Funktion bereitstellen oder eine Funktion, die als
extern inline
deklariert ist. Diese eine Übersetzungseinheit wird als Bereitstellung der
externen Definition
bezeichnet. Um undefiniertes Verhalten zu vermeiden, muss eine externe Definition im Programm existieren, wenn der Name der Funktion mit externer Verknüpfung in einem Ausdruck verwendet wird, siehe
One Definition Rule
.
Die Adresse einer Inline-Funktion mit externer Verknüpfung ist immer die Adresse der externen Definition, aber wenn diese Adresse verwendet wird, um einen Funktionsaufruf durchzuführen, ist es nicht spezifiziert, ob die Inline-Definition (falls in der Übersetzungseinheit vorhanden) oder die externe Definition aufgerufen wird. Die statischen Objekte, die innerhalb einer Inline-Definition definiert sind, unterscheiden sich von den statischen Objekten, die innerhalb der externen Definition definiert sind:
inline const char *saddr(void) // die Inline-Definition für die Verwendung in dieser Datei { static const char name[] = "saddr"; return name; } int compare_name(void) { return saddr() == saddr(); // nicht spezifiziertes Verhalten, ein Aufruf könnte extern sein } extern const char *saddr(void); // eine externe Definition wird ebenfalls erzeugt
Ein C-Programm sollte nicht davon abhängen, ob die Inline-Version oder die externe Version einer Funktion aufgerufen wird, andernfalls ist das Verhalten nicht spezifiziert.
Schlüsselwörter
Hinweise
Das
inline
Schlüsselwort wurde von C++ übernommen, aber in C++ muss eine Funktion, die als
inline
deklariert ist, in jeder Übersetzungseinheit als
inline
deklariert werden, und jede Definition einer Inline-Funktion muss exakt gleich sein (in C können die Definitionen unterschiedlich sein, und je nach Unterschieden führt dies nur zu nicht spezifiziertem Verhalten). Andererseits erlaubt C++ nicht-konstante funktionslokale Statics und alle funktionslokalen Statics aus verschiedenen Definitionen einer Inline-Funktion sind in C++ gleich, aber in C unterschiedlich.
Beispiel
Header-Datei "test.h"
#ifndef TEST_H_INCLUDED #define TEST_H_INCLUDED inline int sum(int a, int b) { return a + b; } #endif
Quelldatei "sum.c"
#include "test.h" extern inline int sum(int a, int b); // stellt externe Definition bereit
Quelldatei "test1.c"
#include <stdio.h> #include "test.h" extern int f(void); int main(void) { printf("%d\n", sum(1, 2) + f()); }
Quelldatei "test2.c"
#include "test.h" int f(void) { return sum(3, 4); }
Ausgabe
10
Referenzen
- C23-Standard (ISO/IEC 9899:2024):
-
- 6.7.4 Function specifiers (S.: TBD)
- C17-Standard (ISO/IEC 9899:2018):
-
- 6.7.4 Funktionsspezifizierer (S: TBD)
- C11-Standard (ISO/IEC 9899:2011):
-
- 6.7.4 Funktionsspezifizierer (S: 125-127)
- C99-Standard (ISO/IEC 9899:1999):
-
- 6.7.4 Funktionsspezifizierer (S: 112-113)
Siehe auch
|
C++ Dokumentation
für
inline
Spezifizierer
|