C++不使用匿名命名空间实现内部链接

Posted

技术标签:

【中文标题】C++不使用匿名命名空间实现内部链接【英文标题】:C++ achieve internal linkage without using anonymous namespaces 【发布时间】:2018-09-10 08:16:09 【问题描述】:

我一直在阅读有关声明匿名命名空间以缩短链接时间的文章。

但是,我已经读过,确实不建议在头文件中声明匿名命名空间:

在头文件中定义未命名的命名空间时,可能会导致令人惊讶的结果。由于默认的内部链接,每个翻译单元将定义其自己的唯一实例,该实例是在该翻译单元内 ODR 使用的未命名命名空间的成员。这可能会导致意外结果、使生成的可执行文件膨胀,或由于违反单一定义规则 (ODR) 而无意中触发未定义行为。

以上是从下面的链接中摘录的一段话,其中有几个匿名命​​名空间的意外行为示例: https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file

所以,我的问题是:

上述问题仅适用于匿名命名空间变量,不适用于方法。对吗?

使用 static 关键字强制与变量进行内部链接时是否会出现同样的问题?如果是这样,有没有其他方法可以安全地实现这一目标?

【问题讨论】:

“膨胀生成的可执行文件” - 适用于函数。恕我直言,安全的方法是在标头中声明具有内部链接的事物时知道您在做什么,无论您如何声明它们。 如果你想让事物有内部链接,也许你根本不应该把它们放在头文件中。 是的,同样的逻辑适用于头文件中的static 函数或变量,就像它适用于头文件中的匿名namespace。头文件不是放置内部链接的正确位置。 【参考方案1】:

上述问题仅适用于匿名命名空间变量,不适用于方法。对吗?

提到的问题发生在匿名命名空间内的任何东西上。

使用 static 关键字强制与变量进行内部链接时是否会出现同样的问题?

同样的事情发生。

如果是这样,有没有其他方法可以安全地实现这一目标?

没有。

如果您将任何具有内部链接的实体(类、变量、成员函数、模板等)放入包含在不同翻译单元中的头文件中,ODR 违规迟早会发生。如果任何具有外部链接的实体在其定义或声明中使用具有内部链接的实体之一,您很快就会遇到问题。

在匿名命名空间内声明的任何实体,那些声明为静态和非外部 const 变量的实体具有内部链接。

据推测,您正在寻找的内容有 2 个部分解决方案:

内联变量和函数的定义可以出现在多个翻译单元中,因此在头文件中定义它们是安全的。

1234563 )

【讨论】:

以上是关于C++不使用匿名命名空间实现内部链接的主要内容,如果未能解决你的问题,请参考以下文章

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

C++之类的基本使用2(在类的内部定义结构和使用)

static关键字在命名空间范围内没用吗?

devc++格式为啥那么丑

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

为啥要将类型放在未命名的命名空间中?