Reputation: 609
I'm aware that mixing debug and release libraries that pass STL containers to each other causes big problems. But what exactly in 'debug' or 'release' causes this?
I have a QT project that gets built as 'release', but it has /DEBUG added to the compiler flags. If I build another QT project under 'debug' (which also has the /DEBUG flag), are they compatible?
Or is there an optimization flag or some other flag that makes them incompatible?
Basically, is there a way I can look at the compilation line of the 2 libraries and see something that says "DON'T MIX THESE!"?
Upvotes: 0
Views: 1336
Reputation: 3022
Firstly the /DEBUG
flag doesn't actually create a 'debug' build. It just tells the linker to generate debugging information and create a .pdb file along with the resulting binary.
As to the difference between the debug and release MSVC++ runtimes the issue is to do with the fact that different runtimes can have different sizes for the same object. e.g. in debug extra information might be placed in iterators to ensure their validity at run time. If code has been compiled against the release version of these structures then corruption is likely. Another issue would be if an object if allocated from the heap of one runtime and is attempted to be freed on the heap of another runtime.
Upvotes: 1
Reputation: 416
Not really. Concerning Visual C++'s STL implementation, there are data members of the containers corresponding to the iterator checking that is only compiled in if some preprocessor variables are set. These variables are default valued base on the NDEBUG preprocessor variable that is quasi standard for "no debug". But these could be also set directly from the command line, or from header files, or Visual Studio property pages, etc.
E.g.: all containers are derived from _Container_base
, while that is a typedef depending on _ITERATOR_DEBUG_LEVEL
. The different _Container_base
implementations have different memory layout, and that is what causes incompatibilities between the debug and release version.
The /DEBUG compiler flag tells the compiler whether to generate debug information or not, and might also affect default values for optimization settings, but I am not sure about that, and of course that is compiler dependent.
Just like there could be an STL implementation that does not depend on any preprocessor directives, and in that case it would not matter how you compile it, debug or release, the memory layout would be identical, and so it could be passed around between modules compiled the different ways.
Upvotes: 1
Reputation: 50016
This is undefined behaviour, so it might work but more probably it will crash your app. It also depends on stl implementation, in debug version it might enable additional checks and allocate additional memory making data layout different in release modes. In the end this violates ODR rule (one definition rule) once again causing undefined behaviour.
I have a QT project that gets built as 'release', but it has /DEBUG added to the compiler flags. If I build another QT project under 'debug' (which also has the /DEBUG flag), are they compatible?
If your Release contains exactly the same compiler flags as Debug then I would say they are compatible.
Or is there an optimization flag or some other flag that makes them incompatible?
you should be able to see those flags, I dont think optimization flags should cause UB problems, its rather different macros used during compilation phase that cause ODR violation. Maybe there are optimization flags which changes alignment in structures...
Basically, is there a way I can look at the compilation line of the 2 libraries and see something that says "DON'T MIX THESE!"?
no idea here.
Why are you mixing differently build libraries in the first place? this is asking for trouble.
Upvotes: 2