【问题标题】:Can a function be defined in global namespace if it is declared in an anonymous namespace?如果函数在匿名命名空间中声明,是否可以在全局命名空间中定义?
【发布时间】:2019-10-29 06:07:53
【问题描述】:

在生产代码中,我在 .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,它找不到函数定义。 但是,它编译和链接没有错误,并且代码完成了它应该做的事情。

我发现 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 编译它就好了。

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

【问题讨论】:

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


    【解决方案1】:

    看看cppreference page on unnamed namespaces

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

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

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

    【讨论】:

    • 有道理,但是如果不是那个,为什么我可以通过::foo() 调用它呢?
    • 我可以。即使使用 gcc
    • 我猜这是隐含的using namespace 的影响,但需要比我更好的语言律师来解释它。
    • @sebrockm 你可以提出一个新问题。
    猜你喜欢
    • 1970-01-01
    • 2018-07-24
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2013-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多