Visual Studio 2013 及更早版本中的 Microsoft C++ (MSVC) 编译器工具集不保证主版本间的二进制兼容性,无法链接由不同版本工具集生成的对象文件、静态库、动态库和可执行文件,因为ABI、对象格式和运行时库不兼容。

微软在 Visual Studio 2015 及更高版本中改变了这个行为。对于自 Visual Studio 2015 以来的所有版本(该版本号都以 14 开头,如Visual Studio 2015、2017、2019 和 2022工具集的版本分别为 v140、v141、v142 和 v143)由其中任一版本编译器编译的运行时库和应用都具有二进制兼容性。

假设你使用 Visual Studio 2015 生成第三方库,你仍可在 Visual Studio 2017、2019 或 2022 生成的应用程序中使用它们,无需使用匹配工具集重新编译。 同时最新版本的 Microsoft Visual C++ 可再发行程序包(运行时库)也兼容所有老版本,无需为不同版本安装不同的运行时库,统一安装最新版本即可。

对二进制兼容性的限制

v140、v141、v142 和 v143 工具集与次要版本号更新之间的二进制兼容性方面存在三个重要限制:

  • 你可以混合使用由 v140、v141、v142 和 v143 工具集的不同版本生成的二进制文件。 但是,必须使用至少与应用中最新二进制文件同样新的工具集进行链接。 下面是一个示例:可以将使用任何版本的v141工具集(版本 15.0 到 15.9)编译的应用链接到使用 Visual Studio 2019 版本 16.2 (v142) 编译的静态库。 只是必须使用版本 16.2 或更高版本工具集链接它们。只要使用 16.4 或更高版本工具集,便可以将版本 16.2 库链接到版本 16.4 应用。

  • 应用使用的可再发行程序包具有类似的二进制兼容性限制。 混合使用由工具集的不同受支持版本生成的二进制文件时,可再发行程序包版本必须至少与任何应用组件使用的最新工具集一样新。

  • 使用 /GL(全程序优化)编译器开关编译或是使用 /LTCG(链接时间代码生成)链接的静态库或对象文件不在各个版本间二进制兼容(包括次要版本更新)。

    使用 /GL/LTCG 编译的所有对象文件和库必须将完全相同的工具集用于编译和最终链接。 例如,使用 Visual Studio 2019 版本 16.7 工具集中的 /GL 生成的代码无法链接到使用 Visual Studio 2019 版本 16.8 工具集中的 /GL生成的代码。 编译器会发出错误 C1047

从 Visual Studio 2015 及更高版本升级 Microsoft Visual C++ 可再发行程序包

对于 Visual Studio 2015、2017、2019 和 2022,微软将 Microsoft Visual C++ 可再发行程序包的主版本号保持一致。 这意味着我们一次只能安装可再发行程序包的一个实例。 较新版本会覆盖已安装的任何较旧版本。 例如,一个应用可能会从 Visual Studio 2015 安装可再发行程序包。 随后另一个应用从 Visual Studio 2022 安装可再发行程序包。 2022 版本会覆盖较旧版本,但由于它们具有二进制兼容性,早期应用仍可正常工作。 微软确保最新版本的可再发行程序包具有所有最新的功能、安全更新和 bug 修补程序。 这便是为什么微软始终建议升级到最新可用版本。

同样,已安装了较新版本时,无法安装较旧的可再发行程序包。 如果尝试,则安装程序会报告错误。 如果在已具有 2022 版本的计算机上安装 2017 或 2019 可再发行程序,则会看到如下所示的错误:

1
0x80070666 - Another version of this product is already installed. Installation of this version cannot continue. To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel.

此错误是微软故意这样设计的,以确保Microsoft Visual C++ 可再发行程序包为最新版本。

本文参考:Visual Studio 版本之间的 C++ 二进制兼容性