Visual Studio 2012更新是否会破坏C++ ABI?

Blo*_*ops 18 c++ abi visual-studio-2012

当Microsoft最初于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版本)?链接.lib不同的VS2012版本是否安全?

我在互联网上搜索了一段时间,但未找到微软的任何明确声明.有些消息来源提到C++代码生成中的一些错误已得到修复,但我认为这并不意味着ABI的变化?

Eoi*_*oin 13

Visual C++的STL实现的主要作者Stephan T. Lavavej在这个Reddit线程中规定了规则:

以下是准确的规则:

如果包含任何C++标准库头文件,则必须遵循其规则,并且我们有意破坏主要版本之间的二进制兼容性(但保留在修补程序和服务包之间).任何表示更改(包括但不限于添加/删除数据成员)都会破坏二进制兼容性,这就是为什么这总是会发生以及为什么我们小心翼翼地保护这一权利.

[剪断]

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

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

但是请注意,当加载到单个进程中的多个二进制文件使用不同的主要版本进行编译时,您几乎肯定会最终将多个CRT加载到您的进程中,这是不可取的.

底线 - 如果你100%一致地编译所有内容,你就不必担心任何这些东西.如果你可以避免它,不要玩混合游戏.


Blo*_*ops 7

最后,我在Stephan T. Lavavej的博客文章中找到了我的问题的答案:C++ 11/14 STL功能,修复和VS 2013中的重大变化:

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

像Visual C++ 2013这样的主要版本让我们可以自由地改变和破坏很多东西.我们根本无法在更新中发送这些内容.

Q5:错误修正怎么办?我们可以在更新中获得这些吗?

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

每个团队都可以选择将哪些错误修正为"shiproom"以考虑包含在更新中.有些东西会让我们逃脱(例如,在主要版本之外禁止二进制破坏变更),但除此之外我们还有自己决定事情的自由度.我个人优先考虑带宽超过延迟 - 也就是说,我更倾向于在每个主要版本中发布更多的错误修正,而不是在多个更新中更频繁地发送错误修正总数(在相同的时间段内).