Freigeben über


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 gibt extern an, dass die Variable oder Funktion in einer anderen Übersetzungseinheit definiert ist. Die extern 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. Die extern muss auf alle Deklarationen in allen Dateien angewendet werden. (Globale const-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. Der extern "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 von extern 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