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

标签 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 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/

相关文章:

c++ - 卡萨布兰卡:在 linux centos 上的汇编错误 gcc 4.8.1

c - C如何打印一个超大数?

c++ - Visual C++ 2012 (x86) 中可能的编译器错误?

c++ - __attribute__((__packed__)); 之间有什么区别?和#pragma pack(1)

c++ - 结构和类之间的区别?

c++ - SDL tilemap 渲染很慢

C++类成员初始化&构造函数定义

c - 为什么当符号存在时 clang 会产生链接问题?

c# - 从 C++ 传递到 C# 的字符串打印空白

c++ - 为什么 OnKeyDown 不捕获基于对话框的 MFC 项目中的按键事件?