繁体   English   中英

C++ ODR 违规和共享库

[英]C++ ODR violation and shared libraries

假设我们有一个静态链接到 MyLib1.0 的程序。 还有一个与 MyLib1.1 链接的共享库。

现在如果程序加载这个共享库会发生什么? 我的假设是在运行时我们将对相同的符号有多个不同的定义。

以下两种情况是否都违反了 ODR?

  1. 共享库导出所有符号,包括MyLib1.1的符号
  2. 共享库隐藏了MyLib1.1的所有符号

动态链接或动态加载共享库是否重要?

有一些类似的问题,但到目前为止我找不到非常明确的答案。

从定义“单一定义规则”的 ISO C++ 标准的角度来看,没有 static 或动态链接的概念。 只有翻译单位。

如果您的程序包含以两种不同方式定义同一实体的翻译单元(例如,因为定义随MyLib的 1.1 版而更改),那么这就是 ODR 违规,并且该程序具有未定义的行为,无论您如何链接该程序。

除此之外的所有内容都特定于链接在给定平台上的工作方式,尽管当然其中很多是常见行为,例如共享库可以覆盖符号并具有自身的本地符号。

编译器具有标志和属性来指定此行为,例如 GCC 具有-fvisibility标志和__attribute__((visbility(/*...*/)))属性。 指定一个符号是共享库的本地符号并不意味着它在程序中使用另一个版本时是兼容的。 例如,如果 class 的 memory 布局在版本之间发生变化,并且 object 在使用不同版本的程序的两个部分之间传递,它们很可能以不兼容的方式访问 memory,从而导致实际意义上的未定义行为(而不是然后标准的)。

链接不同库版本的特定组合是否有效取决于很多因素。 因此,只有在库作者声明支持时才应该这样做。 他们需要明确注意对库的更改是二进制/ABI 兼容的。 当使用不同版本的标头时,这已经是正确的,而不仅仅是在实际链接它时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM