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

时间:2018-03-31 14:27:42

标签: c++ linkage

我一直在阅读声明匿名命名空间以实现更低的链接时间。

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

  

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

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

所以,我的问题是:

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

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

1 个答案:

答案 0 :(得分:1)

  

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

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

  

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

同样的事情发生了。

  

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

没有。

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

在匿名命名空间内声明的任何实体,声明为static和not-extern const变量的实体都有内部链接。

根据您的意愿,您可以找到2个部分解决方案:

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

  • 如果您要查找的内容不是要在您正在写入的库外部显示名称,请在私有标头中定义它们并应用它们可见性属性([[gnu:visibility("hidden")]]或不{{1对于MSVC)