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
Если файл заголовка содержит объявленную extern
constexpr
переменную, ее необходимо пометить __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
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по