определение глобальной константной переменной – доступ через extern в С++
-
21-12-2019 - |
Вопрос
Я прочитал несколько ответов по этой теме, но все еще не уверен:
В C++ автоматически определяется глобальная константная переменная. static
.Однако я могу получить к нему доступ из другого cpp-файла через extern:
// module.cpp
const int i = 0;
и
// main.cpp
extern const int i;
int main ()
{
if (i > 10)
return 0;
else
return 1;
}
Почему это возможно (доступ к объекту с внутренней связью из другого модуля)?Обычно я должен быть вынужден определить i
как extern const int i = 0
в модуле.cpp, чтобы явно указать глобальная, но нестатическая константа, или?
Для сравнения, это невозможно:
// module.cpp
static int i = 0;
и
// main.cpp
extern int i;
int main ()
{
i = 10; // but read-only access like (i > 10) would be possible!
return 0;
}
Таков и ответ:да, вы можете получить доступ к внутренним связанным объектам из других модулей, но только для чтения (так что всегда с константой)?
Редактировать:
Извините, но я допустил ошибку:в моем исходном коде я только что попробовал выражение без эффекта (в обоих примерах):
extern const int i; // or extern int i for second example
int main ()
{
i>10;
return 0;
}
Я думал, что оно ведет себя так же, как если бы поток программы или данные зависели от этого выражения, но на самом деле это не так!Компилятор как будто просто вырезал это бесполезное выражение, чтобы компоновщик его не увидел!Так что все в порядке:в первом примере i
действительно должно быть определено extern const int i = 0
в модуле.cpp и во втором примере i
не может быть доступен вообще (если только в бесполезном выражении).Компилятор — VC++2010.
Редактировать2:
Однако теперь я не понимаю, почему это возможно:
// module.cpp
extern const int i = 0;
и
// main.cpp
int i = 99;
int main ()
{
bool b = i>10;
return 0;
}
i
иметь обе внешние связи.Но никакой ошибки.Когда в модуле.cpp я определяю int i = 0
, затем ошибка (несколько символов).Почему?
Решение
На мой взгляд это похоже на ошибку компилятора.Константная переменная i не определена. Она объявлена только в main.cpp.Что касается переменной i в модуле.cpp, то она имеет внутреннюю связь и не должна быть доступна вне модуля.
Что касается вашего дополнения к исходному сообщению, то компилятор не имеет ничего общего с этой ситуацией.Именно компоновщик проверяет наличие дублирующихся внешних символов.Я думаю, он решил, что если у одной переменной есть квалификатор const, а у другой его нет, то это две разные переменные.Я думаю, что реализация определяет, выдаст ли компоновщик ошибку или нет.Более того, у него могут быть некоторые опции, которые могут контролировать поведение компоновщика в таких ситуациях.