Следует ли избегать безымянных функций пространства имен, чтобы уменьшить размеры таблицы символов?

Я слышал, как утверждается, что использование безымянных пространств имен в 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 ++ или стандарт требует компилятора для создания записей для таких функций? Если это раздувание считается ошибкой, существуют ли известные компиляторы, для которых это не проблема?

2

Решение

Правда ли, что использование статического объявления перед функцией вместо помещения его в безымянное пространство имен приводит к тому, что функция становится недоступной вне модуля компиляции, в котором она определена?

Да.

Namespace-static устарел в C ++ 03 в пользу безымянных пространств имен, но на самом деле ун-устаревшим для C ++ 11 когда все поняли, что это одно и то же и не было никакого смысла в обесценивании.

Есть ли разница между этими двумя подходами

Нет, не совсем. Из-за использования пространства имен могут быть некоторые тонкости в поиске имен, но сейчас я не могу придумать ничего.

кроме того, что потенциально не вызывает рост таблицы символов?

Так как это language-lawyer Вопрос без очевидной практической проблемы, которую я должен решить, я должен указать, что язык C ++ не имеет понятия таблицы символов и, следовательно, не указывает на этот эффект.

Это также не будет иметь никакого заметного эффекта, пока у вас не появятся десятки тысяч безымянных пространств имен; вы?

4

Другие решения

Причиной для безымянного пространства имен и устаревания статического уровня пространства имен является неудачное ключевое слово export.

Все, на что опирается экспортируемый шаблон, должно быть доступно для ссылок в точках реализации, которые, скорее всего, находятся в разных исходных файлах. Безымянное пространство имен допускает статический аспект приватизации, сохраняя при этом связь для экспортируемых шаблонов.

Теперь, когда экспорт был удален в C ++ 2011, я уверен, что требование внешней связи для безымянного пространства имен было удалено, и теперь оно ведет себя точно так же, как статический уровень пространства имен. Кто-то более знакомый со стандартом может подтвердить / опровергнуть это.

0

По вопросам рекламы [email protected]