Переменная с квалификацией const (file-local; .cpp), объявленная в области пространства имен, имеет внутреннюю связь и, таким образом, является локальной единицей перевода. Есть ли причина / эффект для сохранения константы в анонимном пространстве имен?
Например, есть ли причина предпочесть любой из следующих двух, и если да, то почему?
// file.cpp
namespace foo {
const int kMyLocalConstant = 42; // internal linkage
} // namespace foo
против
// file.cpp
namespace foo {
namespace {
const int kMyLocalConstant = 42; // internal linkage
} // namespace
} // namespace foo
Я благодарен за ответы на C++ 03, а также на C++ 11, если есть какие-то отличия между ними для этого контекста.
Возможные дубликаты
Я прочитал отличный ответ на
но я не вижу, чтобы он отвечал на мой конкретный вопрос (поправьте меня, если я ошибаюсь), поскольку ответ фокусируется на неконстантных идентификаторах переменных и нестатических бесплатных функциях. Мой вопрос касается констант с областью имен локального файла, то есть идентификаторов переменных, которые уже имеют внутреннюю связь. Может быть, есть более подходящий обман, которого я не нашел.
Безымянное пространство имен является избыточным, в этом случае его использование бесполезно.
Единственный случай, когда я бы поместил const
в безымянное пространство имен, - это когда есть другие вещи (функции и т. д.), Которые тоже должны иметь внутреннюю связь, а const
и другие вещи согласованы.
Сильно предпочитаю безымянное пространство имен.
Почему? Потому что это упрощает запоминание правила: если я создаю переменную / функцию / шаблон, который должен быть локальным для единицы перевода, я безоговорочно помещаю ее в безымянное пространство имен, и тогда мне не нужно снова о чем-нибудь беспокоиться.
Верно, что не встроенная переменная энергонезависимого типа с квалификацией const, которая не была явно объявлена как extern и ранее не была объявлена как имеющая внешнюю связь также будет иметь внутреннюю связь, но действительно ли вы собираетесь поместить свои неконстантные переменные в безымянное пространство имен, а константные - вне его? Это может привести к ошибкам, если вы случайно забудете const
:
// some_tu.cpp
namespace foo {
int oops = 42;
}
А вы бы когда-нибудь смешивали и сочетали? Это странно:
// some_other_tu.cpp
namespace foo {
const int a = 0;
namespace {
int b;
}
}
Безымянные пространства имен бесплатны - единственная стоимость - количество символов, необходимых для их ввода. А это значит, что никто не должен смотреть на этот код и вспоминать обо всех тонкостях правил [basic.link].
@dfri Ага, Формулировка C++ 11. В какой-то момент добавлена формулировка и про volatile
.
Спасибо за этот ответ, Барри. Думаю, помимо переменных
inline
(C++ 17?), По сути, такое же довольно исчерпывающее правило [basic.link] также справедливо для C++ 03 и C++ 11? То есть определение связи переменной области пространства имен никогда не было тривиальным упражнением.