2

This SO post: Is Visual-C++-2017 binary compatible with VC++-2015? clearly says that VS 2017 is binary compatible with VS 2015. It even looks like the official position.

My question is, in the past, I distinctly remember running into linker errors (I do not recall the specific set of errors) every time I try to link in a static library that was compiled with a different version of MSVC into an EXE that is being built with a newer version of MSVC.

Yet, binary (in)compatibility sounds like something that will blow up in your face at runtime, not link time.

Can someone tell me if previous versions of MSVC did indeed producer linker errors on version mismatches? How was this accomplished?

EDIT

How does this affect static libraries built with WPO/LTCG turned on? I believe these produce intermediate object files (as opposed to COFF) and Microsoft did not guarantee the format of these intermediate files to remain stagnant across different versions of the compiler.

ForeverLearning
  • 6,352
  • 3
  • 27
  • 33
  • https://msdn.microsoft.com/en-us/library/ee956429.aspx – Hans Passant Jun 01 '17 at 11:49
  • @HansPassant Sorry, I don't understand. Are you saying static libs built with, say VS2013, automatically place a pragma_detect directive unbeknownst to me so if I try to link against it from a different compiler, the linker error shows up? (i.e no intervention from me?) – ForeverLearning Jun 01 '17 at 13:57
  • 1
    "Automatic" is not exactly the right word. This #pragma appears in the #include files you use in your program. It is a generic mechanism, the compiler's include files just take advantage of it to detect gross mismatches. It embeds the /FAILIFMISMATCH "foo=bar" linker directive into the object file, the linker simply collects all foos and verifies that they are all bar. Just grep the files in the vc/include directory for the #pragma to see them being used. – Hans Passant Jun 01 '17 at 14:06
  • @HansPassant Indeed! I see it now. As I said in my EDIT above, I had turned WPO/LTCG on which produced intermediate object files that don't work with dumpbin. So I couldn't see any of these symbols. Just to round out my understanding, are you saying VS 2017 ignores these FAILIFMISMATCH checks? VS 2017 should still complain if I try to use a static lib built with *VS 2013*, right? – ForeverLearning Jun 01 '17 at 14:49
  • 1
    The VS2017 linker does not ignore them. You do not have a guarantee that the include files of an old compiler already generated the /FAILIFMISMATCH that you like. The mechanism is relatively new (VS2010 and up) and foo flavors are being added with each release. – Hans Passant Jun 01 '17 at 15:04
  • @HansPassant I can't say I have got the zen of it yet but I am getting closer. I built a static lib on VS 2015 and ensured that I saw `/FAILIFMISMATCH:_MSC_VER=1900` in the resulting .obj file. Now I built an EXE with VS 2017 and linked against this static lib. Everything built nicely. So either VS 2017 doesn't care if _MSC_VER=1900 or something else is going on. – ForeverLearning Jun 01 '17 at 15:12
  • 1
    That is what "binary compatible" means. Specific to VS2017 vs VS2015, doubtful that the next release will be binary compatible as well. We'll see. – Hans Passant Jun 01 '17 at 15:14
  • @HansPassant Thanks for the great discussion. I learnt something today. – ForeverLearning Jun 01 '17 at 15:28

2 Answers2

5

As I answered on the linked question, the v140 toolset in VS 2015 and the v141 toolset in VS 2017 are binary compatible. v141 was built as a member of the same "family" as all the updates to v140 (e.g., VS 2015 Update 1, 2, 3) were all in the same family. This was an intentional design decision that helps developers to move to a new version of VS without worrying about having to make changes in their source code.

VS 2017 can support multiple toolsets. The next toolset will not be binary compatible with v140/v141. But you'll still be able to install v141 as you move your code to be compatible with the new C++ features in the next toolset.

Note that we never have supported binary compatibility across major versions. You can't link a binary built with v140 and a binary built with v130, regardless of WPO/LTCG/etc. Yes, it often works--we try to minimize breaking changes in our libraries so often it is the case that linking some code across major versions doesn't hit any errors. But eventually you'll run into something that changed and you'll see an error.

As to whether you see a link error or a runtime error, that depends on the incompatible library API that you called. If the exported shape of the API changed--the name of the function, the number of parameters--then the linker will fail to find it. If the shape is the same but the behavior has changed, you can end up with a runtime failure.

--Andrew Pardoe, MSVC tools

apardoe
  • 631
  • 6
  • 10
  • Thanks Andrew. The point behind the WPO/LTCG question was that I was unsure whether binary compatibility takes care of even intermediate object file format. Because IIUC, aside from binary compat, the issue with WPO/LTCG is the object file format varies across toolchains. – ForeverLearning Jun 01 '17 at 18:07
  • Yep, as I said: you may be able to link some code across releases but you'll eventually run into something that breaks. – apardoe Jun 02 '17 at 21:01
  • How about v141 and v140_xp? I'm converting a v140_xp project to v141, and suddenly running into crashes caused by the asp.net dll which doesn't have a specific version toolset as far as i can see – T.S Nov 15 '17 at 11:29
  • v140 and v141 should be compatible. the _xp variants are the same tools used with a different SDK. – apardoe Nov 16 '17 at 18:48
2

Microsoft claims that they are compatible, and this is supported by the compiler verison number which was just bumped from 1400 to 1410 this time:

https://blogs.msdn.microsoft.com/vcblog/2017/03/07/binary-compatibility-and-pain-free-upgrade-why-moving-to-visual-studio-2017-is-almost-too-easy/

Bengt Gustafsson
  • 517
  • 4
  • 10
  • I am unable to mark yours as accepted answer but thanks for the link! I had read this post back in March but completely forgot about it. – ForeverLearning Jun 01 '17 at 18:09