Namensräume
Varianten
Aktionen

inline-Funktionsspezifizierer

Von cppreference.com
< c‎ | Sprache

Deklariert eine Inline-Funktion.

Inhalt

[bearbeiten] Syntax

inline funktionsdeklaration (seit C99)

[bearbeiten] Erklärung

Die Absicht des inline-Spezifizierers ist es, dem Compiler einen Hinweis für Optimierungen zu geben, wie z.B. Function Inlining, was normalerweise erfordert, dass die Definition einer Funktion an der Aufrufstelle sichtbar ist. Compiler können die Anwesenheit oder Abwesenheit des inline-Spezifizierers für Optimierungszwecke ignorieren (und tun dies normalerweise auch).

Wenn der Compiler Function Inlining durchführt, ersetzt er einen Aufruf dieser Funktion durch ihren Körper und vermeidet so den Overhead eines Funktionsaufrufs (Platzierung von Daten auf dem Stapel und Abrufen des Ergebnisses), was zu einer größeren ausführbaren Datei führen kann, da der Code der Funktion mehrmals wiederholt werden muss. Das Ergebnis ist ähnlich wie bei Funktionsähnlichen Makros, mit dem Unterschied, dass Bezeichner und Makros, die in der Funktion verwendet werden, sich auf die an der Stelle der Definition sichtbaren Definitionen beziehen und nicht auf die an der Stelle des Aufrufs.

Unabhängig davon, ob Inlining stattfindet oder nicht, sind die folgenden Semantiken von Inline-Funktionen garantiert:

Jede Funktion mit interner Bindung kann als static inline ohne weitere Einschränkungen deklariert werden.

Eine nicht-statische Inline-Funktion kann keine nicht-konstante statische Funktion auf lokaler Ebene definieren und kann sich nicht auf eine statische Variable auf Dateiebene beziehen.

static int x;
 
inline void f(void)
{
    static int n = 1; // error: non-const static in a non-static inline function
    int k = x; // error: non-static inline function accesses a static variable
}

Wenn eine nicht-statische Funktion als inline deklariert wird, muss sie in derselben Übersetzungseinheit definiert werden. Die Inline-Definition, die extern nicht verwendet, ist nicht extern sichtbar und verhindert nicht, dass andere Übersetzungseinheiten dieselbe Funktion definieren. Dies macht das Schlüsselwort inline zu einer Alternative zu static für die Definition von Funktionen in Header-Dateien, die in mehreren Übersetzungseinheiten desselben Programms enthalten sein können.

Wenn eine Funktion in einigen Übersetzungseinheiten als inline deklariert wird, muss sie nicht überall als inline deklariert werden: Höchstens eine Übersetzungseinheit darf auch eine reguläre, nicht-inline, nicht-statische Funktion oder eine als extern inline deklarierte Funktion bereitstellen. Diese eine Übersetzungseinheit liefert die sogenannte *externe Definition*. Um undefiniertes Verhalten zu vermeiden, muss eine externe Definition im Programm vorhanden sein, wenn der Name der Funktion mit externer Bindung in einem Ausdruck verwendet wird, siehe Regel für eine Definition.

Die Adresse einer Inline-Funktion mit externer Bindung ist immer die Adresse der externen Definition. Wenn diese Adresse jedoch für einen Funktionsaufruf verwendet wird, ist es nicht spezifiziert, ob die *Inline-Definition* (falls in der Übersetzungseinheit vorhanden) oder die *externe Definition* aufgerufen wird. Die in einer Inline-Definition definierten statischen Objekte sind von den in der externen Definition definierten statischen Objekten getrennt.

inline const char *saddr(void) // the inline definition for use in this file
{
    static const char name[] = "saddr";
    return name;
}
 
int compare_name(void)
{
    return saddr() == saddr(); // unspecified behavior, one call could be external
}
 
extern const char *saddr(void); // an external definition is generated, too

Ein C-Programm sollte sich nicht darauf verlassen, ob die Inline-Version oder die externe Version einer Funktion aufgerufen wird, andernfalls ist das Verhalten nicht spezifiziert.

[bearbeiten] Schlüsselwörter

inline

[bearbeiten] Anmerkungen

Das Schlüsselwort inline wurde von C++ übernommen. In C++ muss eine als inline deklarierte Funktion in jeder Übersetzungseinheit als inline deklariert werden, und auch jede Definition einer Inline-Funktion muss exakt gleich sein (in C können die Definitionen unterschiedlich sein, und je nach Unterschied führt dies nur zu nicht spezifiziertem Verhalten). Auf der anderen Seite erlaubt C++ nicht-konstante lokale statische Variablen, und alle lokalen statischen Variablen aus verschiedenen Definitionen einer Inline-Funktion sind in C++ gleich, aber in C unterschiedlich.

[bearbeiten] 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); // provides external definition

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

[bearbeiten] Referenzen

  • C23-Standard (ISO/IEC 9899:2024)
  • 6.7.4 Funktionsspezifizierer (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)

[bearbeiten] Siehe auch

C++ Dokumentation für den inline-Spezifizierer