Compartir a través de


extern (C++)

La palabra clave extern se puede aplicar a una declaración de variable, función o plantilla global. Especifica que el símbolo tiene externuna vinculación. Para obtener información general sobre la vinculación y por qué no se recomienda el uso de variables globales, consulte Unidades de traducción y vinculación.

La palabra clave extern tiene cuatro significados en función del contexto:

  • En una declaración de variable no global const, extern especifica que la variable o función se define en otra unidad de traducción. extern debe aplicarse en todos los archivos excepto en el que se define la variable.

  • En una declaración de variable const, especifica que la variable tiene una vinculación extern. extern debe aplicarse a todas las declaraciones de todos los archivos. (Las variables globales const tienen vinculación interna de forma predeterminada).

  • extern "C" especifica que la función se define en otro lugar y usa la convención de llamada del lenguaje C. El modificador extern "C" también se puede aplicar a varias declaraciones de función en un bloque.

  • En una declaración de plantilla, extern especifica que ya se ha creado una instancia de la plantilla en otro lugar. extern indica al compilador que puede reutilizar la otra creación de instancias, en lugar de crear una nueva en la ubicación actual. Para obtener más información sobre este uso de extern, vea Creación de instancias explícitas.

extern vinculación para los no globales const

Cuando el enlazador ve extern antes de una declaración de variable global, busca la definición en otra unidad de traducción. Las declaraciones de no variables const que están en el ámbito global son extern de forma predeterminada. Solo se aplica extern a las declaraciones que no proporcionan la definición.

//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 vinculación para los globales const

Una variable global const tiene vinculación interna de forma predeterminada. Si desea que la variable tenga vinculación extern, aplique la palabra clave extern a la definición y a todas las demás declaraciones de otros archivos:

//fileA.cpp
extern const int i = 42; // extern const definition

//fileB.cpp
extern const int i;  // declaration only. same as i in FileA

Vinculación de extern constexpr

En versiones 15.3 o anteriores de Visual Studio 2017, el compilador siempre proporcionaba una vinculación interna de variable de constexpr aunque la variable se marcase como extern. En la versión 15.5 de Visual Studio 2017 y posterior, un nuevo conmutador de compilador /Zc:externConstexpr permite un comportamiento correcto que cumple con los estándares. Esta opción acabará convirtiéndose en el conmutador predeterminado. La opción /permissive- no habilita /Zc:externConstexpr.

extern constexpr int x = 10; //error LNK2005: "int const x" already defined

Si un archivo de encabezado contiene una variable declarada como externconstexpr, debe marcarse como __declspec(selectany) para que tengan sus declaraciones duplicadas combinadas:

extern constexpr __declspec(selectany) int x = 10;

Declaraciones de función extern "C" y extern "C++"

En C++, cuando se usa con una cadena, extern especifica el uso de las convenciones de vinculación de otro lenguaje para los declaradores. Las funciones y datos de C solo están accesibles si se declaran previamente con vinculación de C. Sin embargo, se deben definir en una unidad de traducción compilada por separado.

Microsoft C++ admite las cadenas "C" y "C++" en el campo de string-literal. Todos los archivos de inclusión estándar utilizan la sintaxis de extern "C" para permitir que las funciones de la biblioteca en tiempo de ejecución se usen en programas de C++.

Ejemplo

En el ejemplo siguiente se muestran cómo declarar los nombres que tienen vinculación de 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 una función tiene más de una especificación de vinculación, debe estar de acuerdo. Es un error declarar funciones como que tienen vinculación de C y C++. Además, si en un programa aparecen dos declaraciones para una función (una con una especificación de vinculación y otra sin ella), la declaración con especificación de vinculación debe ser la primera. Cualquier declaración redundante de funciones que ya tengan especificación de vinculación recibe la vinculación especificada en la primera declaración. Por ejemplo:

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 de Visual Studio 2019, cuando /permissive- se especifica, el compilador comprueba que las declaraciones de parámetros de función extern "C" también coinciden. No se puede sobrecargar una función declarada como extern "C". A partir de la versión 16.3 de Visual Studio 2019, puede invalidar esta comprobación mediante la opción /Zc:externC- del compilador después de la opción /permissive-.

Consulte también

Palabras clave
Unidades de traducción y vinculación
extern Especificadores Storage-Class en C
Comportamiento de identificadores en C
Vinculación en C