【问题标题】:Template instantiation in different translation units compiled with different optimization levels使用不同优化级别编译的不同翻译单元中的模板实例化
【发布时间】:2016-03-14 01:59:17
【问题描述】:

假设我有两个翻译单元,都使用std::string。我用-O3 编译其中一个,另一个没有优化,然后将结果链接在一起。两个目标文件都将包含实例化的std::string,但我希望一个版本可以通过优化编译,而另一个则没有。链接器会在链接期间只选择其中一个吗?如果有,是哪一个?生成的可执行文件能否保证始终正常运行?

更新:由于这看起来是特定于实现的,因此将其范围缩小到 gcc 和 clang 行为是有意义的,因为它们都实现了定义明确且具体的 Itanium ABI,而不是试图从C++ 标准本身的视图。

【问题讨论】:

  • Both object files would contain instantiated std::string. 它们将仅包含 string 的内联成员函数。其余的都带有libstdc++。在这种情况下,与任何其他内联函数的行为相同,链接器将选择一个,可能是您传递给链接器的第一个目标文件中的那个。我假设如果唯一改变的是优化级别(而不是某些预处理器定义),那么你应该没问题。

标签: c++ templates gcc linker template-instantiation


【解决方案1】:

就 C++ 标准而言,这可能是最左边的领域。对于初学者来说,C++ 标准没有关于“优化级别”或任何其他方面的内容。

因此,这完全属于“实现定义”的范围。答案取决于您使用的确切编译器/链接器和编译器/链接器版本。一个编译器或链接器的正确答案将仅适用于该编译器或链接器。不同的编译器,甚至是同一编译器的不同版本,都会产生不同的结果。

我会期待以下两种结果之一:

A) 链接器会抱怨合并不同的段,或者

B) 一个或另一个将被随机选择。可能是第一个或最后一个翻译单元被传递给链接器。

因此,总而言之,知道这个问题的答案的唯一方法是让您使用您正在使用的任何编译器或链接器进行尝试,并检查结果。

【讨论】:

  • 只有在标准明确规定的情况下,事物才是实现定义的(这意味着实现必须记录它)。
  • 我已经更新了问题,将其范围缩小到更具体的内容。
  • 另外,我想说更重要的部分是生成的可执行文件是否能正确运行,这更像是一个 ABI 问题。
猜你喜欢
  • 2015-06-04
  • 2011-12-01
  • 1970-01-01
  • 2016-02-16
  • 2018-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多