2
votes

https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2017 says that C++ Binary Compatibility between Visual Studio 2015 and Visual Studio 2017 is guaranteed except:

1)When static libraries or object files are compiled with the /GL compiler switch.

2)When consuming libraries built with a toolset whose version is greater than the toolset used to compile and link the application. For example, a program that is compiled and linked with compiler version 19.12 can consume libraries that are compiled with 19.0 up through 19.12. Also, binary compatibility only exists between Visual Studio 2015 and Visual Studio 2017; linking 19.x programs with libraries produced by Visual Studio 2013 or earlier is not supported.

Exception 2 makes me confused. Why binary compatibility can not be guaranteed in this case?

Let's make it be more specific. Provided a folder which contains a custom exe, a custom dll and part of vc_toolset dlls(v140 or v141). Both the custom exe and the custom dll are linked dynamically to part of vc_toolset dlls which includes CRT dlls, msvcp140.dll, vcruntime140.dll. Besides, /GL option is not enabled.

I list several combinations below. I wonder each one's binary compatibility.

1)exe built by vs2015 + dll built by vs2015 + v140 toolset dlls of vs2015

I think binary compatibility can be guaranteed in this case.

2)exe built by vs2015 + dll built by vs2015 + v141 toolset dlls of vs2017

based on case 1, additionally, toolset dlls were replaced with newer version that's shipped with vs2017.

Also, I think binary compatibility can be guaranteed in this case.

3)exe built by vs2015 + dll rebuilt by vs2017 + v140 toolset dlls of vs2015

base on case 1, the custom dll was rebuilt using vs2017. Then there are two choice:

a) just replace the dll and the exe would not be rebuilt using the new dll's import lib

b) replace the dll and rebuild the exe using the new dll's import lib.

According to the above link's exception 2, binary compatibility can not be guaranteed in a) and b) case. But why ? All the interfaces and dependencies of the custom dll are not changed, and it not rely on v141's new feature.

4)exe built by vs2015 + dll rebuilt by vs2017 + v141 toolset dlls of vs2017

base on case 3, additionally, toolset dlls were replaced with newer version that's shipped with vs2017.

5)exe rebuilt by vs2017 + dll built by vs2015 + v140 toolset dlls of vs2015

base on case 1, the custom exe was rebuilt using vs2017, and linked with the import lib of the custom dll which was previously built by vs2015

According to the above link, I think binary compatibility can be guaranteed in this case.

6)exe rebuilt by vs2017 + dll built by vs2015 + v141 toolset dlls of vs2017

base on case 5, additionally, toolset dlls were replaced with newer version that's shipped with vs2017. if case 5 and case 2 can be guaranteed, I think it's also guaranteed in this case.

Is my understanding correct?

2
compatibility will be guaranteed when exe and dll are build with the exactly same version of VC++, with same language dialect options, and crt dlls come from that particular VC++.user7860670
What exactly are those "toolset DLL's" you are mentioning that come in VS2015 and VS2017 variants? Because the examples you give (msvcp140.dll) do not have separate 2015 and 2017 versions. Options 2,4 and 6 do not exist.MSalters
@MSalters toolset DLL means CRT dlls, msvcp140.dll, vcruntime140.dll. 2015(v140) and 2017(v141)'s msvcp140.dll has the same name and can be replaced with different version.finn
Well, obviously VS2017 shipped with an up-to-date version of the CRT back then, but that's not relevant today in 2018. When you ship, you ship with the current version of the 140 CRT including all security patches. I think we're currently at v14.15.26706.00.MSalters

2 Answers

1
votes

Since you explicitly call out the

... CRT DLLs ...

I will answer that part:

Backwards Compatibility between the VS2017 CRT and the VS2015 CRT is 100% guaranteed! (Modulo MS Bugs of course.)

How can I say this? The default deployment method for the MSVC CRT is deploying all CRT files to System32, so there is one (1) global set of CRT DLLs that most applications will use. (At least AFAIKT, many many apps use the MS CRT in DLL form, but do not bundle all CRT DLLs in their app directory.)

And with VS 2017 vs. 2015, all CRT DLLs have the same filenames, i.e. msvcp140.dll, vcruntime140.dll, there are no 141 files! (So Bullet Point 6 does not exist.)

So a given Windows system can have at most one global set of CRT140 files, and since no application controls this, newer versions of CRT140 must be backwards compatible to apps built against older versions.


Given that, I would simply not do cases 3 and 5 (with regard to CRT) from your question: Always deploy the newest MS CRT that your components rely upon.

Even found a blog entry wrt. this (2017/03/07):

... The VCRedist is only backward compatible, so you will need to redistribute the latest VCRedist 140 available in VS 2017 with your app. ...


With regard to the bullet point 3 and 4 situation 2015.exe <-> 2017.dllI have created a new question: Is the official binary incompatibility between VS2017 and VS2015 app vs. dll accurate? because this is really weird, IMHO.

0
votes

The main point of the article you cite is that Microsoft has INCREASED the likelihood of ccompatibility between MSVS 2015 and MSVS 2017 binaries.

It lists only two exceptions:

https://docs.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2017

C++ Binary Compatibility between Visual Studio 2015 and Visual Studio 2017

In previous versions of Visual Studio, binary compatibility between object files (OBJs), static libraries (LIBs), dynamic libraries (DLLs), and executables (EXEs) built by using different versions of the compiler toolset and runtime libraries was not guaranteed.

This has changed in Visual Studio 2017. In Visual Studio 2015 and Visual Studio 2017, the C++ toolset major number is 14 (v140 for Visual Studio 2015 and v141 for Visual Studio 2017). This reflects the fact that both the runtime libraries and the applications compiled with either version of the compiler are--for the most part--binary compatible.

This means, for example, that if you have a DLL in Visual Studio 2015, you don't have to recompile it in order to consume it from an application that is built with Visual Studio 2017.

There are two exceptions to this rule. Binary compatibility is not guaranteed in these cases:

  1. When static libraries or object files are compiled with the /GL compiler switch.

  2. When consuming libraries built with a toolset whose version is greater than the toolset used to compile and link the application.