Можно ли определить функцию в глобальном пространстве имен, если она объявлена ​​в анонимном пространстве имен? - PullRequest
5 голосов
/ 14 июня 2019

В рабочем коде я нашел это в файле .cpp:

namespace
{
    void foo(); // declared in anonymous namespace, defined below
}

void bar() // declared in corresponding .h file, defined here
{
    ::foo(); // call foo
}

void ::foo() // intended to refer to the anonymous foo above
{
}

Мы используем Visual Studio 2017. Я наткнулся на это, потому что intellisense дал мне предупреждение для foo, что он не может найти определение функции. Тем не менее, он компилирует и связывает без ошибок, и код делает то, что должен.

Я набросился на него и обнаружил, что gcc и clang отклоняют этот код по той же причине, по которой intellisense дал мне предупреждение.

Итак, мой вопрос: Какой компилятор правильный и почему?


Кроме того, из интереса я добавил еще одно объявление foo в глобальное пространство имен, например:

namespace
{
    void foo();
}

void foo(); // another declaration

void bar()
{
    ::foo(); // which foo will be called?
}

void ::foo() // which foo will be defined?
{
}

Теперь gcc выдает ошибку:

ошибка: явное определение в объявлении 'void foo ()'

Clang компилирует его, но выдает предупреждение:

предупреждение: дополнительная квалификация участника 'foo' [-Wextra-qualification]

И msvc прекрасно его компилирует.

Опять же, какой компилятор - если есть - здесь правильный?

1 Ответ

6 голосов
/ 14 июня 2019

Взгляните на страницу cppreference для безымянных пространств имен :

Это определение рассматривается как определение пространства имен с уникальным именем и директивой использования в текущемобласть действия, которая назначает это безымянное пространство имен.

Таким образом, «анонимное» пространство имен не является глобальным пространством имен и даже не имеет названия.Скорее, оно имеет уникальное имя, предоставленное компилятором.Так что ::foo() - это , а не функция в вашем анонимном пространстве имен.MSVC здесь неверен.

И вы не можете определить свою анонимную функцию пространства имен вне ее анонимного пространства имен .

...