在生产代码中,我在.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 Studio2017。我无意中发现了这一点,因为intellisense向我警告了foo
,因为它找不到函数定义。
但是,它可以编译和链接而不会出错,并且代码可以执行预期的工作。
我对它进行了错误的发现,发现gcc和clang拒绝了此代码,其原因与智能感知给我警告的原因相同。
所以我的问题是:哪个编译器正确,为什么?
此外,出于兴趣,我向全局名称空间添加了另一个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编译就可以了。
再次,哪一个编译器(如果有)在这里正确?
答案 0 :(得分:6)
看看cppreference page on unnamed namespaces:
此定义被视为具有唯一性的名称空间的定义 名称和在当前范围内提名该名称的using指令 未命名的命名空间。
因此,“匿名”名称空间既不是全局名称空间,也不是未命名的。而是,它具有编译器提供的唯一名称。因此,::foo()
不是匿名名称空间中的函数。 MSVC在这里不正确。
还有you can't define your anonymous namespace function outside its anonymous namespace。