关于匿名命名空间和内部链接的标准是啥?

Posted

技术标签:

【中文标题】关于匿名命名空间和内部链接的标准是啥?【英文标题】:What standard says about anonymous namespace and internal linkage?关于匿名命名空间和内部链接的标准是什么? 【发布时间】:2020-01-29 08:23:34 【问题描述】:

我很好奇这个事实,因为我想出了以下代码:

namespace

    int my_variable = 12;
    void get_data_a_lot() 



int main()

    my_variable++;

    get_data_a_lot();

并用 msvc 编译我得到以下信息:

00E 00000000 SECT4  notype       External     | ?my_variable@?A0x087c0a53@@3HA (int `anonymous namespace'::my_variable)
025 00000000 SECT6  notype ()    Static       | ?get_data_a_lot@?A0x087c0a53@@YAXXZ (void __cdecl `anonymous namespace'::get_data_a_lot(void))

但是当我使用 gcc 编译时,我得到以下信息:

002 00000000 SECT2  notype       Static       | _ZN12_GLOBAL__N_111my_variableE
003 00000000 SECT1  notype ()    Static       | _ZN12_GLOBAL__N_114get_data_a_lotEv

所以问题是:“my_variable”是外部的还是编译器错误是正确的行为?

【问题讨论】:

但是 MSVC 您可以从另一个翻译单元访问它吗?名字修饰可能是它不可能的原因。 我知道它不能从另一个 TU 访问,但我认为链接器会将它作为输入并尝试处理它。所以链接会变慢。也许我错了。请纠正我,如果它以其他方式工作。 您使用的是哪个版本的 MSVC?哪个版本的 GCC?您将哪些标志和选项传递给编译器?编译器遵循哪个 C++ 标准?因为unnamed namespaces的链接规则随着C++11标准的变化而变化。 @Andrei - 我严重怀疑它对链接速度有明显影响,当然还不足以保证将其称为 QoI 错误。令人惊讶,也许。我愿意答应你。 @Someprogrammerdude。 C++14,O0 两者。 MSVC 2017,mingw gcc 8.3.0 【参考方案1】:

标准说

[basic.link]

4 未命名的命名空间或直接声明的命名空间或 间接在未命名的命名空间内具有内部链接。所有其他 命名空间具有外部链接。具有命名空间范围的名称 上面没有给出内部链接 与上面的链接相同 封闭命名空间,如果它是名称

一个变量;或 [...]

根据my_variable应该有内部链接。然而,必须牢记如何 链接的实现完全取决于实现。 MSVC 没有标记符号Static 的事实并不意味着它违反了标准。所有标准要求的是一个实体,其名称具有内部链接,与其他 TU 中具有相同名称的实体不同,因此它只能在定义它的单个 TU 中由该名称引用。名称修改很可能是MSVC 如何轻松完成它。

【讨论】:

感谢您的回答和参考!我想指出的唯一一点是,在“my_variable”之前添加“静态”一词会使链接“静态”。 02B 00000000 SECTB notype 静态 | ?my_variable@?A0x087c0a53@@3HA (int `匿名命名空间'::my_variable) @Andrei - 看,出于一致性原因,现在这似乎是错误的。这可能是一个错误。

以上是关于关于匿名命名空间和内部链接的标准是啥?的主要内容,如果未能解决你的问题,请参考以下文章

C++问题:关于匿名命名空间

C++:在匿名命名空间中声明函数原型的正确方法是啥?

静态模板成员变量具有内部链接但未定义

用于头文件中的匿名命名空间

下一代门的命名空间前缀、源类型 URI、OSLC 中的链接属性是啥?

C++ 项目相关知识命名空间