статические глобалы и анонимные пространства имен в C ++

11
  1. Почему в C ++ проводилось какое-либо различие между статическими глобальными переменными (внутренняя связь) и символами в безымянном пространстве имен (внешняя связь, но в любом случае нет возможности ссылаться на нее извне) при представлении последнего?

  2. Какие-либо из этих причин все еще действительны, или есть новые?

  3. Есть ли места, где они все еще различны, кроме произвольного правила, которым должны быть анонимные глобальные (или пространства имен) союзыstatic , и каковы они?

  4. Для бонусных баллов, если не осталось веских причин для их отличия, есть ли просьба сделать их эквивалентными?


Когда C ++ ввел пространства имен (C ++ 98) и, в частности, безымянные пространства имен, статические глобальные перемены устарели как устаревшие и уступали новым в борьбе за энтузиазм, хотя это было отменено в C ++ 11 :
Устаревание статического ключевого слова… больше не надо?

До C ++ 11 символы с внутренней связью не могли использоваться в качестве аргументов шаблона: почему C ++ 03 требовал, чтобы параметры шаблона имели внешнюю связь?

Deduplicator
источник
Похоже, вы в основном ответили на свой вопрос, за исключением бита «соответствующая реализация»; возможно, вам следует рассмотреть вопрос об удалении второй половины и публикации вместо нее ответа? Или здесь что-то осталось без ответа?
Кайл Стрэнд
@KyleStrand Переформулировал все это.
Дедупликатор

Ответы:

3

Я не думаю, что это отвечает на все ваши вопросы (или любые из них?), Но ключевое различие между статическими объявлениями на уровне файлов и анонимными пространствами имен заключается в том, что пространства имен также применяются к типам (вы не можете объявить staticтип в в том же смысле, что вы объявляете переменную), поэтому пространство имен предпочтительнее, поэтому существует одна идиома для объявления данных и типов в рамках файла.

Например, следующий код должен хорошо скомпилироваться. (Не очень полезно, так как вы не можете различить оба типа, но допускается)

#include <iostream>

struct Foobar
{
    int   foo;
    float bar;
};

namespace
{

struct Foobar
{
    double baz;
};

} // namespace

int main()
{
    std::cout << "HELLO!\n";
}

Живой тест здесь .

glampert
источник
Он компилируется, потому что вы не используете Foobar в основной функции.
дшил
Что еще более важно, что произойдет, если другой файл .cpp объявит свою собственную версию struct Foobar? Хуже того, предположим, что сейчас class Foobar. Подумайте, как вы планируете создавать конструкторы для них обоих.
dgnuff