extern (C++)

extern Ключевое слово может применяться к глобальной переменной, функции или объявлению шаблона. Он указывает, что символ имеет externал-компоновку. Общие сведения о компоновке и причинах использования глобальных переменных не рекомендуется, см. в разделах "Единицы перевода" и "Компоновка".

Ключевое слово extern имеет четыре значения в зависимости от контекста:

  • В объявлении, отличномconst от глобальной переменной, указывает, extern что переменная или функция определена в другом модуле перевода. Он extern должен применяться во всех файлах, кроме тех, где определена переменная.

  • В объявлении переменной const указывается, что переменная имеет externсвязь. Он extern должен применяться ко всем объявлениям во всех файлах. (Глобальные const переменные имеют внутреннюю компоновку по умолчанию.)

  • extern "C" указывает, что функция определена в другом месте и использует соглашение о вызовах на языке C. extern "C" Модификатор также может применяться к нескольким объявлениям функций в блоке.

  • В объявлении шаблона указывает, extern что шаблон уже создан в другом месте. extern сообщает компилятору, что он может повторно использовать другой экземпляр, а не создать новый в текущем расположении. Дополнительные сведения об этом использовании см. в разделе "Явное создание экземпляровextern".

extern компоновка для неconst глобальных

Когда компоновщик отображается extern перед объявлением глобальной переменной, он ищет определение в другом модуле перевода. Объявления не переменных в глобальныхconst область по умолчанию являются external. Применяется extern только к объявлениям, которые не предоставляют определение.

//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 компоновка для const глобальных

Глобальная const переменная имеет внутреннюю компоновку по умолчанию. Если вы хотите, чтобы переменная была externсвязана друг с другом, примените extern ключевое слово к определению и ко всем другим объявлениям в других файлах:

//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

В Visual Studio 2017 версии 15.3 и более ранних версиях компилятор всегда дал constexpr переменную внутреннюю компоновку, даже если переменная была помечена extern. В Visual Studio 2017 версии 15.5 и более поздних /Zc:externConstexpr версиях переключатель компилятора обеспечивает правильное поведение, соответствующее стандартам. В конечном итоге параметр станет значением по умолчанию. Параметр /permissive- не включает /Zc:externConstexpr.

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

Если файл заголовка содержит объявленную externconstexprпеременную, ее необходимо пометить __declspec(selectany) правильно, чтобы ее повторяющиеся объявления были объединенными:

extern constexpr __declspec(selectany) int x = 10;

extern "C" и extern "C++" объявления функций

В C++, при использовании со строкой, extern указывает, что соглашения о компоновке другого языка используются для декларатора. Доступ к функциям и данным C можно получить только в том случае, если они ранее объявлены как имеющие связь C. Однако они должны быть определены в блоке трансляции, который компилируется отдельно.

Microsoft C++ поддерживает строки "C" и "C++" в поле строкового литерала . Все стандартные файлы включают в extern "C" себя синтаксис, позволяющий использовать функции библиотеки во время выполнения в программах C++.

Пример

В следующем примере показано, как объявить имена, имеющие компоновку 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;

Если функция имеет несколько спецификаций компоновки, они должны согласиться. Это ошибка объявления функций как компоновки C и C++. Кроме того, если в программе происходят два объявления для функции, одна с спецификацией компоновки и без нее, объявление с спецификацией компоновки должно быть первым. Ко всем повторным объявлениям функций, уже имеющих спецификацию компоновки, применяется компоновка из первого объявления. Например:

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.

Начиная с Visual Studio 2019, когда /permissive- указано, компилятор проверка, которые также соответствуют объявлениям extern "C" параметров функции. Вы не можете перегружать функцию, объявленную как extern "C". Начиная с Visual Studio 2019 версии 16.3, этот проверка можно переопределить с помощью /Zc:externC- параметра компилятора после этого /permissive- параметра.

См. также

Ключевые слова
Единицы перевода и компоновка
externОписатель класса служба хранилища в C
Поведение идентификаторов в C
Компоновка в C