Binary compatibility between VS2017 and VS2015
Asked Answered
A

2

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.

Arnhem answered 31/5, 2017 at 15:27 Comment(8)
msdn.microsoft.com/en-us/library/ee956429.aspxOlodort
@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?)Arnhem
"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.Olodort
@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?Arnhem
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.Olodort
@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.Arnhem
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.Olodort
@HansPassant Thanks for the great discussion. I learnt something today.Arnhem
S
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

Setzer answered 1/6, 2017 at 17:45 Comment(4)
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.Arnhem
Yep, as I said: you may be able to link some code across releases but you'll eventually run into something that breaks.Setzer
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 seeVirgiliovirgin
v140 and v141 should be compatible. the _xp variants are the same tools used with a different SDK.Setzer
C
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/

Choosey answered 1/6, 2017 at 17:30 Comment(1)
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.Arnhem

© 2022 - 2024 — McMap. All rights reserved.