extern
(C++)
Das Schlüsselwort extern
kann auf eine globale Variable, Funktion oder Vorlagendeklaration angewendet werden. Sie gibt an, dass das Symbol über eine externe Verknüpfung verfügt. Hintergrundinformationen zur Verknüpfung und dazu, warum die Verwendung von globalen Variablen abgeraten wird, finden Sie unter Übersetzungseinheiten und Verknüpfung.
Das Schlüsselwort extern
hat je nach Kontext vier Bedeutungen:
In einer nicht-
const
globalen Variablendeklaration gibtextern
an, dass die Variable oder Funktion in einer anderen Übersetzungseinheit definiert ist. Dieextern
muss in allen Dateien angewendet werden, mit Ausnahme der Datei, in der die Variable definiert ist.In einer
const
Variablendeklaration gibt sie an, dass die Variable über eine externe Verknüpfung verfügt. Dieextern
muss auf alle Deklarationen in allen Dateien angewendet werden. (Globaleconst
-Variablen weisen standardmäßig eine interne Verknüpfung auf.)extern "C"
gibt an, dass die Funktion an anderer Stelle definiert ist und die C-Sprache-Aufrufkonvention verwendet. Derextern "C"
-Modifizierer kann auch auf mehrere Funktionsdeklarationen in einem Block angewendet werden.In einer Vorlagendeklaration gibt
extern
an, dass die Vorlage bereits an anderer Stelle instanziiert wurde.extern
teilt dem Compiler mit, dass er die andere Instanziierung wiederverwenden kann, anstatt an der aktuellen Position eine neue Instanz zu erstellen. Weitere Informationen zu dieser Verwendung vonextern
finden Sie unter Explizite Instanziierung.
extern
-Verknüpfung für nicht-const
Globale
Wenn der Linker vor einer globalen Variablendeklaration extern
sieht, wird in einer anderen Übersetzungseinheit nach der Definition gesucht. Deklarationen von Nicht-Variablenconst
im globalen Bereich sind standardmäßig extern. Wenden Sie nur extern
auf die Deklarationen an, welche die Definition nicht angeben.
//fileA.cpp
int i = 42; // declaration and definition
//fileB.cpp
extern int i; // declaration only. same as i in FileA
//fileC.cpp
extern int i; // declaration only. same as i in FileA
//fileD.cpp
int i = 43; // LNK2005! 'i' already has a definition.
extern int i = 43; // same error (extern is ignored on definitions)
extern
-Verknüpfung für const
-Globale
Eine const
globale Variable weist standardmäßig eine interne Verknüpfung auf. Wenn Sie möchten, dass die Variable eine externe Verknüpfung aufweist, wenden Sie das extern
Schlüsselwort auf die Definition und auf alle anderen Deklarationen in anderen Dateien an:
//fileA.cpp
extern const int i = 42; // extern const definition
//fileB.cpp
extern const int i; // declaration only. same as i in FileA
extern constexpr
-Bindung
In Visual Studio 2017, Version 15.3 und früher, gab der Compiler immer eine interne Verknüpfung mit constexpr
-Variable aus, auch wenn die Variable als extern
markiert wurde. In Visual Studio 2017, Version 15.5 und höher, ermöglicht der /Zc:externConstexpr
-Compilerschalter das korrekte Verhalten von standards-conforming. Schließlich wird die Option zum Standard. Die Option /permissive-
aktiviert /Zc:externConstexpr
nicht.
extern constexpr int x = 10; //error LNK2005: "int const x" already defined
Wenn eine Headerdatei eine Variable enthält, die als extern
constexpr
deklariert ist, muss sie als __declspec(selectany)
markiert werden, damit die doppelten Deklarationen kombiniert werden:
extern constexpr __declspec(selectany) int x = 10;
extern "C"
- und extern "C++"
-Funktionsdeklarationen
Wenn sie mit einer Zeichenfolge verwendet wird, gibt extern
in C++ an, dass die Bindungskonventionen einer anderen Sprache für die Deklaratoren verwendet werden. Auf C-Funktionen und -Daten kann nur dann zugegriffen werden, wenn sie zuvor wie eine C-Bindung deklariert wurden. Allerdings müssen sie in einer separat kompilierten Übersetzungseinheit definiert sein.
Microsoft C++ unterstützt die Zeichenfolgen"C"
und "C++"
im string-literal-Feld. Alle Standardincludedateien verwenden die Syntax extern "C"
, um die in C++-Programmen verwendeten Laufzeitbibliotheksfunktionen verwenden zu können.
Beispiel
Das folgende Beispiel zeigt, wie Namen mit C-Verknüpfung deklariert werden:
// Declare printf with C linkage.
extern "C" int printf(const char *fmt, ...);
// Cause everything in the specified
// header files to have C linkage.
extern "C" {
// add your #include statements here
#include <stdio.h>
}
// Declare the two functions ShowChar
// and GetChar with C linkage.
extern "C" {
char ShowChar(char ch);
char GetChar(void);
}
// Define the two functions
// ShowChar and GetChar with C linkage.
extern "C" char ShowChar(char ch) {
putchar(ch);
return ch;
}
extern "C" char GetChar(void) {
char ch;
ch = getchar();
return ch;
}
// Declare a global variable, errno, with C linkage.
extern "C" int errno;
Wenn eine Funktion mehrere Verknüpfungsspezifikationen enthält, müssen sie übereinstimmen. Fehler beim Deklarieren von Funktionen als C- und C++-Verknüpfung. Wenn darüber hinaus zwei Deklarationen für eine Funktion in einem Programm auftreten – eine mit einer Verknüpfungsspezifikation und eine ohne – muss die Deklaration mit der Verknüpfungsspezifikation die erste sein. Alle redundanten Deklarationen von Funktionen, die bereits eine Verknüpfungsspezifikation haben, erhalten die in der ersten Deklaration angegebene Bindung. Zum Beispiel:
extern "C" int CFunc1();
...
int CFunc1(); // Redeclaration is benign; C linkage is
// retained.
int CFunc2();
...
extern "C" int CFunc2(); // Error: not the first declaration of
// CFunc2; cannot contain linkage
// specifier.
Ab Visual Studio 2019 überprüft der Compiler, ob die Deklarationen extern "C"
-Funktionsparameter ebenfalls übereinstimmen, wenn /permissive-
angegeben wird. Eine als extern "C"
deklarierte Funktion kann nicht überladen werden. Ab Visual Studio 2019, Version 16.3, können Sie diese Überprüfung überschreiben, indem Sie die Compileroption /Zc:externC-
nach der Option /permissive-
verwenden.
Weitere Informationen
Schlüsselwörter
Übersetzungseinheiten und Verknüpfungen
extern-Speicherklassenspezifizierer in C
Verhalten von Bezeichnern in C
Verknüpfung in C