Mixing STL debug/release libraries

会有一股神秘感。 提交于 2019-12-25 04:48:30

问题


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


回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/31810635/mixing-stl-debug-release-libraries

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!