Пространства имён (namespace) предназначены для организации кода, чтобы избежать конфликтов имён (особенно в больших проектах и библиотеках). Обычные пространства имён позволяют группировать классы, функции, переменные и т. д.
Анонимные пространства имён (namespace { ... }) используются для ограничения области видимости внутри одного файла — всё объявленное в них не видно за пределами файла. Ранее для этого использовали модификатор static для функций и переменных на уровне файла, но сейчас предпочтительнее анонимное пространство имён.
// В mylib.cpp namespace { void helper() { // ... } int hidden_var = 42; }
Можно ли считать, что объявление функции/переменной с static на уровне файла и в анонимном пространстве имён всегда приводит к одному и тому же эффекту?
Ответ:
Нет, есть различия. static ограничивает видимость только в текущем файле. Объекты внутри анонимного пространства имён имеют ту же локальную видимость, но получают уникальное имя для каждого файла компиляции, что предотвращает конфликт имен между translation units. В то же время, анонимные пространства имён поддерживают вложенность и могут содержать классы, тогда как static — нет.
История
-При миграции старого кода один модуль использовал static для переменной, другой — аналогичную переменную с тем же именем, но без static. Возникла ошибка компоновки (linker error) из-за множественного определения переменной.
История
-В большом проекте слияние нескольких библиотек привело к невидимым конфликтам между static-функциями разных файлов (одинаковое имя, разные реализации). В результате одна библиотека стала вести себя непредсказуемо после сборки.
История
-Разработчик поместил объявление класса в анонимное пространство имён только в .cpp-файле, что сделало невозможным доступ к классу из других файлов, нарушив архитектуру модуля.