Visual Studio 2012的更新会破坏c++ ABI吗?

Do Visual Studio 2012 updates break C++ ABI?

本文关键字:c++ ABI Studio 2012 更新 Visual      更新时间:2023-10-16

当微软最初在2012年9月发布Visual Studio 2012时,他们宣布他们计划更定期地为Visual Studio提供更新。此后,他们于2012年11月发布了Visual Studio 2012 Update 1 (Visual Studio 2012.1),并于2013年4月发布了Visual Studio 2012 Update 2 (Visual Studio 2012.2)。

我的问题是:更新是否引入了对c++ ABI的任何更改(关于最初的VS2012版本)?链接不同VS2012版本的.lib是安全的吗?

我在网上搜索了一段时间,没有找到微软的任何明确声明。一些消息来源提到c++代码生成中的一些错误已经修复,但我想这并不意味着ABI会发生变化。

Stephan T. Lavavej, Visual c++的STL实现的主要作者在Reddit的帖子中列出了这些规则:

具体规则如下:

如果你包含任何c++标准库头文件,你必须遵守它的规则,我们有意打破主要版本之间的二进制兼容性(但在热修复程序和服务包之间保留它)。任何表示的变化(包括但不限于添加/删除数据成员)都会破坏二进制兼容性,这就是为什么这种情况总是发生的原因,也是为什么我们小心翼翼地保护这种权利的原因。

(剪)

因此,如果您按照STL的规则进行操作,则需要确保以下内容:

    所有链接到一个二进制文件(EXE/DLL)中的目标文件和静态库必须使用相同的主版本进行编译。我们增加了链接器检查,所以不匹配的VS 2010+主要版本将在链接时触发硬错误,但如果涉及VS 2008或更早的版本,我们无法帮助你(没有时间机器)。因为ODR适用于此,所以对于所有目标文件和静态库,您确实应该使用相同的工具集(即相同的服务包级别)。例如,我们修复了vs2010 RTM和SP1之间的std::string内存泄漏,但是如果你混合使用RTM和SP1,生成的二进制文件可能会也可能不会受到泄漏的影响。(另外,您需要使用相同的_ITERATOR_DEBUG_LEVEL和release/debug设置;我们现在有链接器检查这些
  • 如果你有多个二进制文件加载到同一个进程中,并且它们相互传递c++标准库对象,这些二进制文件必须用相同的主版本和_ITERATOR_DEBUG_LEVEL设置构建(发布/调试也应该匹配,我忘记了你是否可以在这里摆脱不匹配)。重要的是,我们无法检测到违反此规则的行为,因此取决于您是否遵守。
  • 接口为纯C或COM(或现在的WinRT)的多个二进制文件可能在内部使用不同的主版本,因为这些东西保证了二进制文件的兼容性。如果你的接口涉及到c++核心语言(例如虚拟的东西),但非常小心地从不提到任何c++标准库类型,那么你可能是好的——编译器真的试图避免破坏二进制兼容性。

但是,请注意,当加载到单个进程中的多个二进制文件使用不同的主版本编译时,您几乎肯定会最终将多个crt加载到您的进程中,这是不希望看到的。

底线-如果你100%一致地编译所有东西,你就不必担心任何这些东西。如果可能的话,不要玩混音游戏。

最后,我在Stephan T. Lavavej的博客文章中找到了我的问题的答案c++ 11/14 STL功能,修复,以及VS 2013中的突破性变化:

VS Update机制主要用于发布高优先级的错误修复,而不是发布新功能,特别是带有破坏性更改的大规模重写(这与同样大规模的编译器更改相关联)。

像Visual c++ 2013这样的主要版本给了我们改变和破坏很多东西的自由。我们根本不可能在更新中发布这些东西。

Q5: bug修复怎么样了?我们能更新一下吗?

A5:这是一个有趣的问题,因为答案取决于我的选择(而在前一个问题中,即使我想,我也不会被允许在更新中发布这样的重写)。

每个团队都可以选择他们要"修复"的错误。考虑纳入更新。有些事情是shiprom不会让我们逃避的(例如在主版本之外禁止二进制破坏更改),但除此之外,我们有决定事情的自由。我个人优先考虑带宽而不是延迟——也就是说,我更喜欢在每个主要版本中发布更多的bug修复总数,而不是在多个更新中更频繁地发布较少的bug修复总数(在同一时间段内)。