Are Visual C++ 2013 binaries compatible with Visual C++ 2017 binaries? - c++

In one of our C++ solutions, we use 3rd part libraries. These libraries are compatible to VS 2013. Now we are migrating our solution to VS 2017 and found that some of the 3rd party libraries do not have VS 2017 compatible versions.
So we tried to use some of the VS2013 compatible libraries in VS20173 and the tried API calls work fine.
Can I assume that the libraries work with VS 2017 executable without any issues?

In general - no. AFAIK, VC++2015 (aka toolset v140) and VC++2017 (aka toolset v141) are stated to be binary compatible. No such statement were made wrt VC++2013, and I believe there are breaking changes (like sizeof(list) etc).
It might work, but could lead to hard-to-debug problem
Microsoft statement:
"A more-severe kind of change, the breaking change can affect binary compatibility, but these kinds of binary compatibility breaks only occur between major versions of Visual Studio. For example, between Visual Studio 2013 and Visual Studio 2015."
see https://learn.microsoft.com/en-us/cpp/porting/visual-cpp-change-history-2003-2015

Nothing is guaranteed but binary compatibility of Visual C++ compilers is generally better than officially announced. Just make sure you do not create/destroy object across different runtimes, propagate exceptions and do not pass STL related objects as parameters.
If the third party libraries expose C style interfaces and they are compiled as DLLs the task is even easier. So you should review those interfaces and verify how much they vary from the general interoperability guidelines.

Related

What provids C/C++ runtime libraries?

I have following 2 questions wrt to Windows SDK and Platform toolsets and C/C++ runtime library.
a) What is the relation of Windows SDK with C/C++ runtime and platform toolset?
Is it correct to say that BOTH C++ runtime libraries & platform toolsets are provided by Windows SDK?
Since we mostly deal with Platform toolsets from within the Visual Studio project settings, so want to understand that whether under the hood does the Visual Studio controls the C++ runtime library and platform toolset versions by installing the required version of Windows SDK?
b) Another thing i wanted to clarify was that if it is correct to say one version of platform toolset can work with different version of Windows SDK OR these are totally unrelated?
eg. in my Visual Studio i see that 'Windows SDK version' is Windows 10 and Platform toolset is v142. Can i set the 'Windows SDK version' to Windows 8.1 and keep the toolset as v142? If yes, then what does it mean?
This is confusing me a lot and i can't seem to get the correct picture with so many different explanations from different people.
TL;DR: If you are using Visual C++, and use the standard REDIST instructions from Microsoft Docs, then these details shouldn't really matter to you.
With VS 2015 and later, the "C/C++ Runtime" has been refactored into three pieces:
UCRTBASE.DLL is part of the OS and serviced through Windows Update. There are 'down-level' versions of it included in the Visual C++ REDIST package, but generally you should think of this as the "OS" part. This is the "C Runtime". These headers, import libraries, and are in the Windows 10 SDK. You can find the source for it there as well C:\Program Files (x86)\Windows Kits\10\Source\<version>\ucrt.
MSVCP*.DLL This is the "C++ Runtime" library, basically stuff like std::vector et al. The headers, import libraries, and such are in the Visual C++ product. You can find the source to it on GitHub per this blog post.
VCRUNTIME*.DLL has the entry-points needed at runtime for the Visual C++ compiler language features.
There are also a few auxiliary libraries as well for specific scenarios:
VCCORLIB*.DLL is used for C++/CX extensions (a.k.a. /ZW)
VCAMP140.DLL is used for C++ AMP
VCOMP140.DLL is used for OpenMP
CONCRT*.DLL is used to implement C++11 <thread> on Windows XP (not used on newer versions of Windows; it's delay loaded if required)
See this blog post and this one.
Essentially the C runtime (the UCRTBASE) part is a simple extern "C" interface so the ABI is well-defined, and thus is usable with multiple versions of Visual C++ and even other compilers. Exactly which version of the UCRT you are using is therefore primarily depending on the OS and the Windows 10 SDK you are using via WindowsTargetPlatformVersion. You can applocal deploy UCRT as well per this blog.
The C++ Runtime (MSVCP*.DLL) includes a lot of inlines and exposed memory layouts, and historically there was a breaking change between between Visual C++ versions. That said, for VS 2015 Update 3, VS 2017, and VS 2019 the VC team has made a point of keeping 'binary compatibly' here meaning that if you have a static library that uses C++ std namespace components from a PlatformToolset of v140/v141, it will successfully link with a later version of Visual C++ up through v142. It's not clear that this will hold in the future, but it is true for this particular set of releases per Microsoft Docs.
The VCRUNTIME*.DLL needs to match the version of the Visual C++ compiler you are using to build the final link, so this is very much intended to match your PlatformToolset.

vc142 and 2019 redistributable package comparison with vc141

Is there a reason (I guess yes but I try to discover it) to install 2019 redistributable when deploying a C++ application built with vc142 since applications seems to work perfectly with the previous redistributable package (coming with vc141)? I have in mind that both are binary compatible, but more than that, dumpbin /exports of msvcp140.dll and vcruntime140.dll from 2017 and 2019 redistributable produce the same output; file size are identical too.
Did I miss something?
Apparently there is no gotcha, the libraries are comptible, see : https://learn.microsoft.com/en-us/cpp/porting/binary-compat-2015-2017?view=vs-2019
The article states: "This reflects the fact that both the runtime libraries and the applications compiled with either version of the compiler are binary compatible."
Maybe there are performance related differences.
As vs 2019 supports later c++ standard than 2017, this leaves one to wonder how this is possible with the old runtime libraries. I guess the differences are all built into the main executable/dll and don't require any changes in the runtime dlls.

Is std::string header only in Visual Studio?

It looks like std::string is a header only file at Community/VC/Tools/MSVC/?/include/xstring, and all generated code should be included inside a build target.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Update 1:
I got many downvotes for this question so let me explain why I decided to ask it.
I'm faced with strange crash, and I can not understand why this happen.
I use latest Qt 5.13.0 (MSVC2017_x64) and also I have some external libraries compiled with Visual Studio 2017. All have /MDd, I checked this with dumpbin util.
When I try to run any code that invokes Qt library and std::string, I'm getting wrong result (and crash at the end).
Here is very simple example:
#include <QApplication.h>
int main(int argc, char** argv) {
QString s1("Test");
std::string s2 = s1.toStdString(); // here we have s2 variable with wrong internal structure
return 0;
}
My idea was that QtCore DLL library has std::string with internal structure not compatible with std::string from Visual Studio 2017. But Qt was created with Visual Studio 2017 (maybe not same as my current Visual Studio, because there was several minor releases), so I decided to ask here if they are compatible or not.
Update 2:
Problem was in _ITERATOR_DEBUG_LEVEL. Looks like Qt was compiled with level 2 and all my external libraries and application were compiled with level 0.
This option affects internal structure of many C++ standard library classes and introduce such side effects. So when we are inside toStdString() and create std::string, we have level 2 and one internal structure. When we are in application code, we have level 0 and another internal structure. We assign object with one internal structure to object with another.
Anyway now I have better understanding of some internals.
how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Because they make a decision to guarantee that, or to not guarantee that.
For example, Visual Studio 2015 to 2019 are binary compatible.
That's a decision that was made, to do that. The result, if what you say is true, is that some of the implementation specifics of std::string on that platform are frozen. This is not unusual for libraries. libstdc++'s std::list::size was non-compliant to C++11 for many years, because they could not add a needed member variable without breaking binary compatibility.
In short, this is basically a project management decision, and if they ever change the header in a way that breaks things, they will tell you that binary compatibility has been broken and you need to rebuild and relink things accordingly.
As for your Qt issue, it does smell like a binary compatibility issue. But you say that both Qt and your application have been built in Visual Studio 2017 with /MDd, which would appear to rule that out. I would ask the Qt community for further help, possibly with slightly more information about your environment and about where you obtained Qt. Also ensure that you're using the version of Qt that's intended — perhaps there are multiple installations? Which one's on your include path?
Is std::string header only in Visual Studio?
Not entirely, it also depends on parts of the Standard C++ library that are implemented in Microsoft's Visual C++ Runtime. Building a binary with MSVC requires the VC++ runtimes to be linked. Only static libraries may be built without linking to a runtime, and then you must be careful to include none of the headers that require the runtime.
Is the std::string header only in Visual Studio?
(I originally read the headline this way.)
std::string is part of the C++ standard.
To use std::string on any platform that supports standard C++, you should use #include <string>. It is a standard header available with pretty much any C++ compiler.
Every compiler or platform may implement the standard in its own way though. For example with MSVC you can see that xstring is how Microsoft implements std::string under the hood. If you include xstring.h directly you are writing code that depends on the version of MSVC that provides that header. That code would not be portable to other compilers.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Microsoft does not guarantee that the next Visual Studio version will have the same std::string internal structure. In the past the implementation of the standard library has changed with every VC++ runtime release, which is why Windows users end up having dozens of VC++ runtime versions installed in their Add/Remove programs list.
Thankfully Microsoft has given us a guarantee that Visual Studio 2015, 2017, and 2019 all use a binary-compatible C++ runtime. This means that binaries built using the standard library provided in Visual Studio 2015 are compatible with binaries built using 2017 and 2019 too. There is no guarantee (yet) that a future version of Visual Studio will not change the VC++ runtime implemenation again.

Visual Studio 2012 static library with Visual Studio 2017

I am building a static library with Visual Studio 2012 (C++), and want to give it to someone with Visual Studio 2017 so they can build their app and link against it. I will also provide the header files for them to use (but no source code that builds the library). The question is, will they be able to use the 2012 static libraries?
You cannot mix platform toolsets.
However, you can use the 2017 IDE with the 2012 platform toolset, via all project properties in your solution, if you have both versions installed.
A better solution would be to upgrade the library in question to 2017, which shouldn't be too terrible of a chore in most cases.
Absolutely not.
They will either need to build the static libraries themselves or you'll have to ship 2017 versions, and tell them comprehensively which compiler and optimisation settings were used. Therefore I would plump for the former if I were you.
Building an application binary interface (ABI for short) is extremely challenging in C++ - it's one thing that's been lost from the language's roots in C.

Compiler used by Visual Studio for C++?

I have tried searching on the internet but could not find out the compiler used by Visual Studio for C++ applications.
I wanted to know whether it is freely available & whether it can be used for commercial applications.
Traditionally I have been using Turbo C++.
The problem with Visual Studio C++ Express is that it does not work with some applications.
For example, BRL-CAD which is an open source project works properly with the commercial version but gives some problems for the Express edition.
It seems that there is some problem with MinGW compiler as well.
I am told this by the people running that project.
Visual Studio uses the same compiler for all editions. So, the Express edition uses the same compiler as the Professional edition. There are also no restrictions on producing commercial applications, in either case. There are differences in the advanced features offered by the IDE, but the compilers are the same. So whatever your problems are in getting the project to work, it is nothing to do with the compiler.