Я слышал, как утверждается, что использование безымянных пространств имен в C ++ для определения функций и гарантии того, что они не могут быть вызваны извне модуля компиляции, в котором они определены, не очень хорошо в очень больших средах кода, потому что они вызывают рост таблицы символов неоправданно большой, включив записи в эти символы в автоматически сгенерированные пространства имен, которые компилятор C ++ предоставляет, когда они не указаны.
namespace {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
Возможно, это с учетом того, что вышеприведенное должно быть таким же, как выполнение следующих действий:
namespace randomlyGenerateNameHereNotCollidingWithAnyExistingNames {
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
void functionPerhapsInsertedIntoSymbolTable() {
return;
}
}
using randomlyGenerateNameHereNotCollidingWithAnyExistingNames;
Однако действительно ли это так просто, требуется ли компилятору сделать запись в таблице символов для символов в сгенерированном имени пространства имен?
Вместо этого в таких ситуациях я слышал, что предлагается использовать статическое объявление:
// This function can only be accessed from hear to the end of
// any compilation unit that includes it.
static void functionNotInsertedIntoSymbolTable() {
return;
}
Правда ли, что использование статического объявления перед функцией вместо помещения его в безымянное пространство имен приводит к тому, что функция становится недоступной вне модуля компиляции, в котором она определена? Есть ли какая-то разница между этими двумя подходами, кроме того, что они не приводят к росту таблицы символов?
Является ли проблема с раздутием таблицы символов из-за безымянных пространств имен просто ошибкой в некоторых реализациях C ++ или стандарт требует компилятора для создания записей для таких функций? Если это раздувание считается ошибкой, существуют ли известные компиляторы, для которых это не проблема?
Правда ли, что использование статического объявления перед функцией вместо помещения его в безымянное пространство имен приводит к тому, что функция становится недоступной вне модуля компиляции, в котором она определена?
Да.
Namespace-static
устарел в C ++ 03 в пользу безымянных пространств имен, но на самом деле ун-устаревшим для C ++ 11 когда все поняли, что это одно и то же и не было никакого смысла в обесценивании.
Есть ли разница между этими двумя подходами
Нет, не совсем. Из-за использования пространства имен могут быть некоторые тонкости в поиске имен, но сейчас я не могу придумать ничего.
кроме того, что потенциально не вызывает рост таблицы символов?
Так как это language-lawyer
Вопрос без очевидной практической проблемы, которую я должен решить, я должен указать, что язык C ++ не имеет понятия таблицы символов и, следовательно, не указывает на этот эффект.
Это также не будет иметь никакого заметного эффекта, пока у вас не появятся десятки тысяч безымянных пространств имен; вы?
Причиной для безымянного пространства имен и устаревания статического уровня пространства имен является неудачное ключевое слово export.
Все, на что опирается экспортируемый шаблон, должно быть доступно для ссылок в точках реализации, которые, скорее всего, находятся в разных исходных файлах. Безымянное пространство имен допускает статический аспект приватизации, сохраняя при этом связь для экспортируемых шаблонов.
Теперь, когда экспорт был удален в C ++ 2011, я уверен, что требование внешней связи для безымянного пространства имен было удалено, и теперь оно ведет себя точно так же, как статический уровень пространства имен. Кто-то более знакомый со стандартом может подтвердить / опровергнуть это.