Извините за этот вопрос. Но мне очень интересно узнать о ключевом слове extern
в C\C++
.
при поиске объяснений для extern
я узнал, что extern
сообщает компилятору, что переменная или функция уже определены в каком-то другом файле или программе.
Но если это так, то почему мы используем extern
?
поскольку я пробовал некоторые коды следующим образом:
extern int var; int main(void) { var = 10; return 0; }
Этот код дает мне сообщение об ошибке как unresolved external symbol "int var" (?var@@3HA)
.
и если я использую какой-то код, например:
extern int var; int main(void) { int var = 10; return 0; }
Он не показывает никаких ошибок и дает значение такое же, как я определил в основной функции.
Итак, может ли кто-нибудь помочь мне в отношении поведения extern
? Я немного смущен этим. Пожалуйста, простите меня, если это недействительный вопрос. Заранее спасибо.
extern
используется для обозначения переменной в другой единицы перевода («исходный файл»). Например, ваш код в main.c выглядит так:
extern int var; int main(void) { var = 10; return 0; }
Этот код содержит объявление для целого числа с именем var, но не определение, потому что extern явно говорит: «определение для этого есть где-то еще»
Вы можете определить другой исходный файл, скажем, other.c:
int var = 0;
Затем, после добавления этой новой единицы перевода в команду сборки, ваша программа будет хорошо связываться, а код в обоих файлах может работать с общей переменной var
.
Во второй версии вы просто переопределяете объявление extern var
локальной переменной в своей основной функции. Поскольку extern var
больше не используется (ODR-), компоновщик не требует этого, поэтому ваш исполняемый файл может успешно сгенерироваться.
Первая версия завершается с ошибкой, так как вы также должны предоставить определение переменной extern
indeclared, то есть путем связывания с некоторым другим C-файлом, который имеет
int var;
в глобальном масштабе.
Второй преуспевает, поскольку int var = 10;
line в main()
затеняет глобальную декларацию; это, как правило, плохо, если вы хотите, чтобы переменная была extern, то есть разделялась между многими C-файлами. Разумеется, такое совместное использование само по себе также довольно плохое (см. Глобальные переменные ).
extern
используется для указания того, что переменная существует в другом модуле компиляции. Если у тебя есть:
main.cpp
extern int var; int main(void) { var = 10; return 0; }
а также:
var.cpp
int var;
Тогда у вас не было бы ошибки компоновщика, поскольку компоновщик подключил бы использование var
в main.cpp с его объявлением в var.cpp
Во втором примере вы определили extern int var
но никогда не ссылаетесь на него. int var = 10
– это совершенно другой int var
из внешнего. Когда они запускаются, он замечает, что вы никогда не используете переменную extern int var
поэтому не пытайтесь ее искать.
Я предлагаю вам очистить свое понимание определения и объявления переменной.
Ключевое слово extern используется, когда вы хотите сказать, что переменной была выделена память, которую вы хотите только объявить переменной.
Когда вы объявляете какую-либо переменную, используя компилятор ключевого слова extern, попытается найти определение той же переменной, которая может присутствовать до или после объявления.
В первом случае вы просто объявляете переменную, не назначая ей какую-либо память, а не определяющую переменную.
вы можете пройти через это, чтобы лучше понять ключевое слово extern.
Если вы double myvar=5
глобальную переменную, скажем, double myvar=5
в файле file1.cpp, и вы хотите получить доступ к этой переменной в файле file2.cpp, то в файле file2.cpp вы объявляете
extern double myvar;
В C ++ каждый файл называется единицей компиляции. Чтобы файл был скомпилирован в объектный файл, вам нужны все объявленные переменные, но вам не нужно инициализировать или выполнять назначение этих переменных.
Возвращаясь к примеру:
File1.cpp: double myvar=5
это и объявление, и инициализация. Вы можете скомпилировать файл file1.cpp в файл file1.o.
File2.cpp: Предполагая, что вы используете myvar
где-то в файле file2.cpp, а также хотите получить доступ к значению (возможно, после вычисления) в файле file1.cpp. Поэтому, чтобы иметь возможность компилировать файл file2.cpp в file2.o, вы должны объявить extern double myvar
, чтобы файл file2.cpp мог быть скомпилирован. Это порадует компилятор и оставляет задачу для компоновщика.
Теперь, когда вы скомпилировали эти файлы, у вас будут объектные файлы (единицы перевода), названные как (если вы используете g ++) file1.o и file2.o. Теперь это работа компоновщика, чтобы связать их вместе и позволить file2.o получить доступ к myvar
.
Объявление переменной extern
сообщает компилятору, что фактический экземпляр переменной находится где-то в другом месте. Если вы не предоставите его в другом месте, этап ссылки не будет выполнен.
Во втором примере вы вообще не ссылаетесь на объявленную переменную extern
. Вы объявляете новый в рамках своей основной функции, который затеняет глобальную декларацию.