18

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

我的问题是:更新是否对 C++ ABI 进行了任何更改(关于初始 VS2012 版本)?链接.lib不同VS2012版本的s安全吗?

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

4

2 回答 2

13

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

以下是准确的规则:

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

[剪辑]

因此,如果您遵守 STL 的规则,则需要确保以下几点:

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

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

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

于 2013-04-11T14:10:38.630 回答
7

最后,我在 Stephan T. Lavavej 的博文C++11/14 STL Features, Fixes, And Breaking Changes In VS 2013中找到了我的问题的答案:

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

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

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

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

每个团队都可以选择他们将哪些错误修复带到“shiproom”以考虑包含在更新中。有些东西shiproom不会让我们侥幸逃脱(例如,在主要版本之外禁止二进制破坏性更改),但除此之外,我们有决定权的自由。我个人优先考虑带宽而不是延迟——也就是说,我更喜欢在每个主要版本中发布更多的错误修复,而不是在多个更新中更频繁地发布更少的错误修复总数(在同一时间段内)。

于 2013-07-11T08:41:32.113 回答