В рабочем коде я нашел это в файле .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 прекрасно его компилирует.
Опять же, какой компилятор - если есть - здесь правильный?