如果函数是在匿名命名空间中声明的,是否可以在全局命名空间中定义?

时间:2019-06-14 15:11:33

标签: c++ gcc visual-c++ clang language-lawyer

在生产代码中,我在.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编译就可以了。

再次,哪一个编译器(如果有)在这里正确?

1 个答案:

答案 0 :(得分:6)

看看cppreference page on unnamed namespaces

  

此定义被视为具有唯一性的名称空间的定义   名称和在当前范围内提名该名称的using指令   未命名的命名空间。

因此,“匿名”名称空间既不是全局名称空间,也不是未命名的。而是,它具有编译器提供的唯一名称。因此,::foo()不是匿名名称空间中的函数。 MSVC在这里不正确。

还有you can't define your anonymous namespace function outside its anonymous namespace