[英]inline functions and the one definition rule
inline
函数提供了一个定义规则的弱化 - 允许多个定义,尽管有一些限制。 我在网上发现的一个措辞是
要求是每个定义应该相同,这意味着它应该由相同的标记组成并引用相同的项目。
虽然我承认我不知道这是否是确定的。 我也不确定它有多严格。
我正在考虑使用class
定义和/或inline
函数创建标题的情况,我希望它是#include
-able,无论是在C ++ 03,C ++ 11中编译,还是在以后的某些标准中编译。 使用__cplusplus
宏来有条件地更改代码是很自然的,但是ODR会发挥作用吗? 例如, 条件似乎是合理的:
typedef
。 class
。 throw()
或noexcept
。 (这一点特别重要,因为每个析构函数noexcept
在C ++ 11中获取一个隐式的noexcept
。) constexpr
。 override
和/或final
标记一个函数。 [[noreturn]]
和/或[[nodiscard]]
。 [[maybe_unused]]
。 [[fallthrough]]
。 但是,如果有人想要启用#include
这些头文件库以便在不同标准下编译并仍然可以安全地一起使用,那么这些中的哪一个 - 如果有的话 - 实际上是允许的?
一般来说,你不能安全地做这些事情。 安全使用说两种类的定义只有两种方法。 平凡的是,你可以简单地编译两个不同的进程,通过例如共享内存进行通信。 不那么简单,如果出现以下情况,您可以使用两个以两种不同方式定义相同符号A的库:
如果你做了所有这些,那么A确实是库的实现细节,你可以使用多个不同定义A的库。 如果其中任何一个不满意,那么你不能保证上述任何一个都可以工作(虽然有些人会这样做)。
对于不熟悉链接器的人来说,最令人惊讶的结果之一是,如果lib1和lib2都使用符号A,即使它们阻止通过头部的任何泄漏,如果A的可见性是公开的,那么A的单个定义将是用于两个库。 因此lib2将使用lib1的定义,反之亦然。 这很容易导致UB。
在* nix系统上,公共可见性是默认设置,因此您需要确保隐藏符号,这有点神秘。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.