Visual Studio 2015 libc不向后兼容

时间:2015-08-12 09:05:36

标签: visual-studio-2013 visual-studio-2015 backwards-compatibility libc

mbstate_t的定义已从:

更改
typedef int mbstate_t;

typedef struct _Mbstatet
{ // state of a multibyte translation
    unsigned long _Wchar;
    unsigned short _Byte, _State;
} _Mbstatet;

typedef _Mbstatet mbstate_t;

这不是向后兼容的,似乎暗示如果我要使用VS 2015,Windows桌面应用程序的所有组件都需要使用VS 2015进行重新编译。显然,“all”在这里太强大了,只有使用mbstate_t的组件才会受到影响。但是,这仍然不是一个好的情况。

如果我们迁移到VS 2015,是否需要重新编译?我在这里遗漏了一些东西,这意味着这不是问题吗?

鉴于此结构发生了变化,我对VS 2013和2015之间可能存在其他重大变化表示了更大的担忧。这些变化是否存在?

注意:

我已经在MSDN上问了这个问题,但我的直觉告诉我Stack Overflow上会有更多的眼睛:https://social.msdn.microsoft.com/Forums/vstudio/en-US/8e50f348-0b6d-442c-8a1e-b1b8a4288fbc/mbstatet-is-not-backwards-compatible-between-vs-2015-and-vs-2013?forum=vcgeneral#8e50f348-0b6d-442c-8a1e-b1b8a4288fbc

2 个答案:

答案 0 :(得分:1)

回答这个问题。是的,如果您希望更新到较新版本的Visual Studio,则需要重新编译所有内容。 MS保留更改工具链和库的任何部分的权利。有明显的C头和C ++头改变的例子。还有很多其他的东西可以改变,这会使版本之间的二进制兼容性变得困难或不可能。

一些讨论/意见

在我看来,在更新到更新版本的工具链时,您需要重新编译所有内容并非百分之百。强制用户重新编译所有内容以更新到新的工具链可能会非常麻烦。在大型项目中,您可能依赖于许多第三方代码,而这些代码无法重新编译。许多SDK在确保向后兼容性方面花费了大量精力,因此用户无需这样做。

有趣的是,链接器不会禁止链接使用旧版本工具链构建的库。它甚至没有警告!这种行为可能意味着将旧库与新代码链接是可以接受的。

无论如何,我整天都可以为此烦恼。我想指出的一件事是如果你知道你在做什么,那么就可以将使用旧版VS构建的二进制文件与新版本相关联。您必须非常清楚您的代码构建的声明(实际上是您的头文件)是什么,并且知道这些声明未更改或者它们以不会导致运行时错误的方式更改。您还必须确保编译器没有以足够的方式改变处理内置/内在函数等的方式来伤害您。例如,使用带有MSVC的try / catch块将导致自动生成代码以处理异常。这将导致对运行时库提供的函数的隐式调用。这可能很容易将版本更改为版本,您可能会留下未定义的符号或意外行为。

谨慎行事:)

答案 1 :(得分:1)

过去,Visual C ++确实尝试在目标文件(以及静态库)级别维护C运行时库向后兼容性。像mbstate_t这样的不透明类型可能会改变它们的内部表示,但它们不会改变它们的大小。这允许使用较旧版本的CRT头编译的目标文件在与较新版本的CRT链接时起作用。

(请注意,当CRT对象通过DLL边界传递时,这不适用。同一程序中的多个CRT,无论是静态链接还是动态链接,都不兼容。)

但这主要仅适用于C代码。标准C ++库根本不是向后兼容的,实际上有链接器检查来强制执行此操作。 (虽然过时的目标文件是用Visual Studio 2008或更早版本编译的,但不是这样。)C ++ ABI也可能在主要版本之间发生变化,因此C ++对象的布局可能会发生变化。

但是,正如您在Visual Studio 2015中注意到的那样,C运行时库不再向后兼容。 CRT went through a major refactoringmany things changed。其中大多数不再是Visual Studio的一部分,而是is now a part of the Windows operating system。您还注意到,当您尝试将旧二进制文件与新CRT链接时,没有错误或警告。由于旧的CRT在编译的目标文件中没有包含任何版本符号,因此可以知道它们是否使用旧的CRT头编译。