extern
(C++)
A palavra-chave extern
pode ser aplicada a uma variável global, função ou declaração de modelo. Ele especifica que o símbolo tem externvinculação al. Para obter informações em segundo plano sobre a vinculação e por que o uso de variáveis globais é desencorajado, consulte Unidades de tradução e vinculação.
A palavra-chave extern
tem quatro significados dependendo do contexto:
Em uma declaração de variável global não
const
,extern
especifica que a variável ou função é definida em outra unidade de tradução. Oextern
deve ser aplicado em todos os arquivos, exceto aquele em que a variável está definida.Em uma declaração de variável
const
, ela especifica que a variável tem vinculação external.extern
deve ser aplicado a todas as declarações em todos os arquivos. (Variáveisconst
globais têm vinculação interna por padrão.)extern "C"
especifica que a função é definida em outro lugar e usa a convenção de chamada de linguagem C. O modificadorextern "C"
também pode ser aplicado a várias declarações de função em um bloco.Em uma declaração de modelo,
extern
especifica que o modelo já foi instanciado em outro lugar.extern
informa ao compilador que ele pode reutilizar a outra instância, em vez de criar uma nova no local atual. Para obter mais informações sobre esse uso deextern
, consulte Instanciação explícita.
extern
vinculação para não const
globais
Quando o vinculador vê extern
antes de uma declaração de variável global, ele procura a definição em outra unidade de tradução. As declarações de variáveis não const
no escopo global são external por padrão. Aplica extern
somente às declarações que não fornecem a definição.
//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
vinculação para const
globais
Uma variável global const
têm vinculação interna por padrão. Se você quiser que a variável tenha vinculação external, aplique a palavra-chave extern
à definição e a todas as outras declarações em outros arquivos:
//fileA.cpp
extern const int i = 42; // extern const definition
//fileB.cpp
extern const int i; // declaration only. same as i in FileA
Vinculação de extern constexpr
No Visual Studio 2017 versão 15.3 e anteriores, o compilador sempre forneceu uma ligação interna variável constexpr
, mesmo quando a variável era marcada como extern
. No Visual Studio 2017 versão 15.5 e posteriores, o compilador /Zc:externConstexpr
habilita o comportamento correto e em conformidade com os padrões. Em algum momento, isso se tornará o padrão. A opção /permissive-
não habilita /Zc:externConstexpr
.
extern constexpr int x = 10; //error LNK2005: "int const x" already defined
Se um arquivo de cabeçalho contém uma variável declarada extern
constexpr
, ela deve ser marcada __declspec(selectany)
para que suas declarações duplicadas sejam combinadas corretamente:
extern constexpr __declspec(selectany) int x = 10;
extern "C"
e declaração da função extern "C++"
Em C++, quando usada com uma cadeia de caracteres, extern
especifica que as convenções de vinculação de outra linguagem estão sendo usadas para os declaradores. As funções C e os dados podem ser acessados somente se forem declarados anteriormente como tendo vinculação C. No entanto, devem ser definidos em uma unidade de conversão compilada separadamente.
O Microsoft C++ oferece suporte às cadeias de caracteres "C"
e "C++"
no campo string-literal. Todos os arquivos de inclusão padrão usam a sintaxe extern "C"
para permitir que funções da biblioteca em tempo de execução sejam usadas em programas C++.
Exemplo
O exemplo a seguir mostra como declarar os nomes que têm vinculação 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;
Se uma função tem mais de uma especificação de vinculação, elas devem ser correspondentes. É um erro declarar as funções como tendo vinculação C e C++. Além disso, se duas declarações para uma função ocorrem em um programa — uma com uma especificação de vinculação e a outra sem — a declaração com a especificação de vinculação deve ser a primeira. Todas as declarações redundantes de funções que já têm a especificação de vinculação são atribuídas a uma vinculação especificada na primeira declaração. Por exemplo:
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.
A partir do Visual Studio 2019, quando /permissive-
é especificado, o compilador verifica se as declarações dos parâmetros de função extern "C"
também correspondem. Você não pode sobrecarregar uma função declarada como extern "C"
. A partir do Visual Studio 2019 versão 16.3, você pode substituir essa verificação usando a opção /Zc:externC-
do compilador após a opção /permissive-
.
Confira também
Palavras-chave
Unidades de tradução e ligação
extern Especificador de classe de armazenamento em C
Comportamento de identificadores em C
Vinculação em C