0

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!"?

Dtor
  • 590
  • 2
  • 9

3 Answers3

2

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.

marcinj
  • 48,511
  • 9
  • 79
  • 100
  • I'm not mixing them intentionally. I'm having a problem passing a vector from one library to another and I'm pretty sure it's the debug/release thing. But I try to understand exactly what's going on before I make changes, I'd like to be 100% sure rather than assuming because rebuilding made the problem go away. – Dtor Aug 04 '15 at 13:58
  • Maybe the wrong STL library is being linked in? What is it that tells the compiler to link in the debug STL library versus the release library? – Dtor Aug 04 '15 at 13:59
  • in VS you can check in Build -> Configuration Manager which project builds are compiled. The Configuration column should be the same for each line of config table. – marcinj Aug 04 '15 at 14:01
1

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.

Peter B
  • 416
  • 2
  • 7
  • Is there a way that I can see the _ITERATOR_DEBUG_LEVEL value in each of the libraries? – Dtor Aug 04 '15 at 14:00
  • Do you know, does QT set ITERATOR_DEBUG_LEVEL based on if you run qmake release or qmake debug? – Dtor Aug 04 '15 at 14:06
  • I assume that Qt itself does not use Visual C++'s STL implementation, but has its own Qt style containers. Unfortunately I don't know if Qt has an iterator debugging mode, but I would guess it has. But the way how it is turned on or off is definitely different that the way Visual C++'s STL uses, so I would think that ITERTAOR_DEBUG_LEVEL preprocessor macro won't affect Qt. – Peter B Aug 04 '15 at 14:10
1

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.

sjdowling
  • 2,994
  • 2
  • 21
  • 31