Notes
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Le mot clé extern
peut être appliqué à une déclaration de variable globale, de fonction ou de modèle. Cela spécifie que le symbole a une liaison externe. Pour plus d’informations sur la liaison et sur les raisons pour lesquelles l’utilisation de variables globales est déconseillée, consultez Unités de traduction et liaison.
Le mot clé extern
a quatre significations selon le contexte :
Dans une déclaration de variable globale non
const
,extern
spécifie que la variable ou la fonction est définie dans une autre unité de traduction. Le mot cléextern
doit être appliqué dans tous les fichiers, à l’exception de celui où la variable est définie.Dans une déclaration de variable
const
, cela spécifie que la variable a une liaison externe. Le mot cléextern
doit être appliqué à toutes les déclarations dans tous les fichiers. (Les variablesconst
globales ont une liaison interne par défaut.)extern "C"
spécifie que la fonction est définie ailleurs, et utilise la convention d’appel du langage C. Le modificateurextern "C"
peut également être appliqué à plusieurs déclarations de fonction dans un bloc.Dans une déclaration de modèle,
extern
spécifie que le modèle a déjà été instancié ailleurs.extern
indique au compilateur qu’il peut réutiliser l’autre instanciation, au lieu d’en créer une autre à l’emplacement actuel. Pour plus d’informations sur cette utilisation deextern
, consultez Instanciation explicite.
Liaison extern
pour les variables globales non const
Quand l’éditeur de liens voit extern
devant une déclaration de variable globale, il recherche la définition dans une autre unité de traduction. Les déclarations de variables non const
à l’étendue globale sont externes par défaut. Appliquez uniquement extern
aux déclarations qui ne fournissent pas la définition.
//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)
Liaison extern
pour les variables globales const
Une variable globale const
a une liaison interne par défaut. Si vous voulez que la variable ait une liaison externe, appliquez le mot-clé extern
à la définition, ainsi qu’à toutes les autres déclarations dans d’autres fichiers :
//fileA.cpp
extern const int i = 42; // extern const definition
//fileB.cpp
extern const int i; // declaration only. same as i in FileA
Liaison extern constexpr
Dans Visual Studio 2017 15.3 et les versions antérieures, le compilateur traitait toujours une variable constexpr
comme ayant une liaison interne, même si cette variable était marquée extern
. Dans Visual Studio 2017 15.5 et les versions ultérieures, le commutateur de compilateur /Zc:externConstexpr
permet d’obtenir un comportement approprié conforme aux standards. À terme, cette option deviendra la valeur par défaut. L’option /permissive-
n’active pas /Zc:externConstexpr
.
extern constexpr int x = 10; //error LNK2005: "int const x" already defined
Si un fichier d’en-tête contient une variable déclarée extern
constexpr
, elle doit être marquée __declspec(selectany)
pour que ses déclarations dupliquées soient correctement combinées :
extern constexpr __declspec(selectany) int x = 10;
Déclarations de fonction extern "C"
et extern "C++"
En C++, quand extern
est utilisé avec une chaîne, il spécifie que les conventions de liaison d’un autre langage sont utilisées pour le ou les déclarateurs. Les fonctions et les données C sont accessibles uniquement si elles ont été déclarées au préalable comme ayant une liaison C. Toutefois, elles doivent être définies dans une unité de traduction compilée séparément.
Microsoft C++ prend en charge les chaînes "C"
et "C++"
dans le champ de littéral de chaîne. Tous les fichiers include standard utilisent la syntaxe extern "C"
pour permettre l’utilisation des fonctions de bibliothèque runtime dans les programmes C++.
Exemple
L’exemple suivant montre comment déclarer les noms qui ont une liaison C :
// 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;
Si une fonction a plusieurs spécifications de liaison, elles doivent être compatibles. Il est erroné de déclarer des fonctions comme ayant à la fois une liaison C et C++. De plus, si deux déclarations relatives à une fonction ont lieu dans un programme, l’une avec une spécification de liaison, et l’autre sans, la déclaration avec la spécification de liaison doit être la première. Toutes les déclarations redondantes de fonctions qui ont déjà une spécification de liaison sont affectées de la liaison spécifiée dans la première déclaration. Par exemple :
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.
À partir de Visual Studio 2019, quand /permissive-
est spécifié, le compilateur vérifie que les déclarations des paramètres des fonctions extern "C"
correspondent également. Vous ne pouvez pas surcharger une fonction déclarée en tant que extern "C"
. À partir de Visual Studio 2019 version 16.3, vous pouvez remplacer cette vérification en utilisant l’option de compilateur /Zc:externC-
après l’option /permissive-
.
Voir aussi
Mots clés
Unités de traduction et liaison
Spécificateur de classe de stockage extern en C
Comportement des identificateurs en C
Liaison en C