32

какую пользу можно извлечь из подобной конструкции:

namespace{
    int i;
}
αλεχολυτ
  • 28,987
  • 13
  • 60
  • 119
perfect
  • 10,021
  • msdn: и это полезно, когда вы хотите сделать объявления переменных невидимым для кода в других файлах (т.е. дать им внутреннее связывание) без создания именованного пространства имен. Весь код в одном файле можно увидеть идентификаторы в неназванной имен но идентификаторов, вместе с самим имен, не видны за пределами этого файла или, точнее за пределами ЕП. – Grundy Feb 09 '16 at 08:09
  • @Grundy как я понял переменная I будет существовать только в текущем файле и будет доступна только для этого файла? – perfect Feb 09 '16 at 08:12

3 Answers3

38

Польза та же, что и при использовании ключевого слова static — избегание проблем с ODR (one definition rule). Если, к примеру, в заголовке у Вас будет int i;, тогда при подключении в 2 и более .cpp файла Вы получите ошибку линковки — один и тот же символ определён дважды. Если же Вы напишете static int i;, то i станет локальным для каждого объектного файла, в который i попадает — т.е. в каждом cpp будет свой i, в отличии от первого варианта, где i один на всю программу. То же самое происходит когда Вы пишите

namespace{
    int i;
}

i получает внутреннее связывание и, следовательно, проблемы с ODR не будет.

αλεχολυτ
  • 28,987
  • 13
  • 60
  • 119
ixSci
  • 23,825
  • 4
    Связывание (linkage) бывает внешнее (external) и внутреннее (internal). Локального связывания нет. – αλεχολυτ Feb 09 '16 at 09:12
  • @alexolut, ну я это и имел в виду – ixSci Feb 09 '16 at 09:25
  • Я догадывался. Но это как "методы" вместо "функций-членов". Режет глаз и порождает новую базу терминов, что, имхо, не есть гуд. – αλεχολυτ Feb 09 '16 at 09:28
  • 2
    Кстати, стоит отметить, что до C++11 анонимный namespace так же обладал уникальным именем, а вот функции и переменные там могли быть с внешним связыванием (другой вопрос: как к ним добраться): http://en.cppreference.com/w/cpp/language/namespace#Unnamed_namespaces – Monah Tuk Feb 09 '16 at 09:47
  • @MonahTuk про уникальное имя namespace не оч.понял, т.к. в c++14 тоже есть про имя unique (см.7.3.1.1). По поводу как достучаться и т.д. задал вопрос на английском SO. – αλεχολυτ Feb 09 '16 at 09:59
  • @alexolut, заметки(note) в стандарте можно смело пропускать, они не несут никакой «нагрузки», т.е. то, что в них написано не обязательно к исполнению – ixSci Feb 09 '16 at 10:09
  • @alexolut, ну т.е. анонимный namespace не совсем анонимный, его имя просто генерируется компилятором, оно уникально. – Monah Tuk Feb 09 '16 at 10:18
  • @MonahTuk Можете указать какой конкретно пункт поменялся в Стандарте по этому поводу? – αλεχολυτ Feb 09 '16 at 10:20
  • 1
    @alexolut По поводу анонимности - никакой. Т.е. уникальное имя так и генерируется. Только стало гарантироваться internal linkage. Смотреть по ссылке выше или C++11 (draft N3337) §3.5/4. В случае C++03 этот пункт выглядит совершенно иначе, а интерпретировать стандарт иногда то ещё удовольствие. – Monah Tuk Feb 09 '16 at 10:36
12

Для каждого безымянного пространства имён компилятор генерирует уникальное имя, которое отличается от любого другого имени в программе.

namespace __Unique_Name__ {
   int i;
}
using namespace __Unique_Name__;

Особенно полезным свойством безымянных пространств является то, что их можно объявлять внутри других пространств имён, например, именованных.

8

Не именованное пространство имен ограничивает видимость блока в пределах файла, где оно объявлено. Т.е из другого файла непосредственный доступ к переменной i ты уже получить не сможешь

Harry
  • 221,325
WenSiL
  • 504
  • 2
  • 15