在生产代码中,我在 .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。我无意中发现了这一点,因为智能感知向我发出了 foo
的警告,它找不到函数定义。
但是,它编译和链接没有错误,并且代码执行了它应该执行的操作。
我用 bolt 固定了它,发现 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 给我一个错误:
error: explicit qualification in declaration of 'void foo()'
Clang 编译它,但给了我一个警告:
warning: extra qualification on member 'foo' [-Wextra-qualification]
并且 msvc 可以很好地编译它。
同样,哪个编译器(如果有的话)在这里是正确的?
最佳答案
看看 cppreference page on unnamed namespaces :
This definition is treated as a definition of a namespace with unique name and a using-directive in the current scope that nominates this unnamed namespace.
所以“匿名”命名空间不是全局命名空间,甚至也不是未命名的。相反,它有一个编译器提供的唯一名称。所以 ::foo()
不是您的匿名命名空间中的函数。 MSVC 在这里不正确。
和you can't define your anonymous namespace function outside its anonymous namespace .
关于c++ - 如果函数在匿名命名空间中声明,是否可以在全局命名空间中定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56600954/