У меня есть файл заголовка, который содержит следующее определение
const std::string error[] = {"a", "b"};
Сейчас я включаю этот файл в два разных модуля перевода и собираю исходные коды. Все работает, но почему? Ожидается, что это сломается one definition rule
,
Теперь еще интереснее, я меняю тип
const char* error[] = {"a", "b"};
и вот оно, ожидаемая ошибка
multiple definition of `error'
Он работает так же, как и для std :: string для int
, char
, short
и другие интегральные типы. Что это?
const
дает Пространство имен в области видимости переменная внутренняя связь, поэтому она работает так же, как
static const std::string error[] = {"a", "b"};
Второй не работает, потому что это не переменная, которая является const, но char
с он состоит из.
Объявлены глобальные переменные const
иметь внутреннюю связь, как будто они также были объявлены static
, Вы можете определять внутренние переменные с одинаковыми именами в разных единицах перевода, поэтому так и происходит в первом примере — каждый блок, который включает в себя заголовок, получает свою собственную копию массива.
Второй пример не const
— указатели указывают на постоянные объекты, но сами являются изменчивыми. Таким образом, этот массив имеет внешнюю связь и подчиняется правилу единого определения.
От MSDN
В C постоянные значения по умолчанию являются внешними связями, поэтому они могут появляться только в исходных файлах. В C ++ константные значения по умолчанию являются внутренними связями, что позволяет им появляться в заголовочных файлах.