No, you cannot mix debug and release runtime libraries with Visual Studio 2017. They are not ABI compatible.
There additional checks and member variables for debug checks in the C++ runtime and the memory allocation routines add additional space and checks in debug mode.
Example code taken from <xmemory0>
(_Adjust_manually_vector_aligned
)
// Extra paranoia on aligned allocation/deallocation; ensure _Ptr_container is
// in range [_Min_back_shift, _Non_user_size]
#ifdef _DEBUG
constexpr uintptr_t _Min_back_shift = 2 * sizeof(void *);
#else /* ^^^ _DEBUG ^^^ // vvv !_DEBUG vvv */
constexpr uintptr_t _Min_back_shift = sizeof(void *);
#endif /* _DEBUG */
const uintptr_t _Back_shift = reinterpret_cast<uintptr_t>(_Ptr) - _Ptr_container;
_STL_VERIFY(_Back_shift >= _Min_back_shift && _Back_shift <= _Non_user_size, "invalid argument");
Here the _DEBUG
variant of the function allocates additional 2 * sizeof(void*)
for checks, whereas the release variant uses only sizeof(void*)
.
From here it is quite obvious that a pointer created by the release variant and used by the debug variant (or vice versa) would trigger all kinds of confusion and error checks.
Hence the Linker error to prevent this from happening.
That said, it would be possible to mix them under specific circumstances, although I would not recommend it.
You must basically create two partitions, which have a very tight and narrow interface. You must make sure that no data of any kind except PODs or fully opaque data types are transferred between "partitions". Also you cannot statically link both debug and release libraries (because of ABI and symbol clashes) to the same binary.
So you could create an std::string
in your 'Debug' routine, but wouldn't be allowed to pass this to a 'Release' routine. But you would be able to pass the 'std::string::c_str()' return value to the 'Release' routine, because that is just a pointer to char.
To do that you would put all 'release' binaries in one DLL and statically link this DLL with the static 'release' runtime and put all 'debug' binaries in another DLL (or EXE) and statically link this with the 'debug' runtime. That way the runtimes are completely hidden inside their respective DLLs and are not visible to the outside world.
(It is possible to link one or more DLLs with a static runtime and others with the dynamic runtime. But again, I wouldn't recommend it).
Basically this is what happens, when you run your 'debug' application under Windows. You don't need a 'Debug' Windows to run your 'Debug' application. Your 'Debug' application runs fine with the 'Release' Windows, which is using its own 'release' runtimes. It's just that the 'release' runtime used by Windows is completely hidden from your 'debug' release time.