13

I've downloaded a 3rd party library, and built the .lib file in 'release' mode. After adding the lib to my project, if i run my project in release mode, it's fine. But if i run my project in debug mode, i get an error:

_iterator_debug_level value '0' doesn't match value '2;

I could rebuild the library in debug mode, but I don't think I'll need to be debugging the library itself? And I've downloaded prebuilt 3rd party libraries before which only come with a release build (i assume?) that link fine whether my project is in debug or release. I'm wondering how that is done.

terryhau
  • 549
  • 2
  • 9
  • 18
  • Everything can work by sheer luck! I would build the library in debug mode, using the same settings as your project, and be done with it. – Bo Persson Apr 25 '11 at 07:37

2 Answers2

14

If you want to distribute a release library that others can use in either release or debug mode, you need to do two things:

  • Build a DLL, so that you get your own copy of the C runtime library
  • Not share CRT resources, such as the heap, across the library boundary. The biggest thing for C code is that dynamically allocated memory has to be deallocated on the same side of the boundary. For C++ code, you can use the std namespace inside your DLL, but not pass those objects across the boundary.

That's what the pre-built third-party libraries have most likely done. You can do the same thing with your library only if the external interface doesn't share CRT objects. Or you can build separate release and debug versions as static libraries.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Ben, can you explain your answer a little bit more? Does that mean that if my library (pre-built in release) is accepting objects by reference, say a std::string, then, others cannot link my library into their debug build? – Sachin Joseph Sep 16 '15 at 15:48
  • 1
    @Sachin: I mean what I already wrote: "For C++ code, you can use the `std` namespace inside your DLL, but not pass those objects across the boundary" That covers pass by reference and pointer as well as copying (pass by value). – Ben Voigt Sep 16 '15 at 17:47
  • is this restriction because of the debug machinery (_ITERATOR_DEBUG_LEVEL) that Microsoft implements to enhance debugging of STL in the debug build? – Sachin Joseph Sep 20 '15 at 05:04
  • 2
    @SachinJoseph: That's one of the ways that the library differs between debug and release, but it's not the only way. Memory allocators in debug mode store extra information such as the location that called the allocation function. And there might be other things too. – Ben Voigt Sep 20 '15 at 05:09
2

Looks like your debug binary and the library you downloaded use incompatible iterator debug modes. Iterator debugging is usually controlled by macros. Depending on macro values the sizes of interators and many other objects can change. You are lucky that your program emitted useful error message instead of simply crushing.

Check the library documentation and make sure that your project uses the same iterator debug mode. You may also try recompiling the library in release mode. If that doesn't help, you would have to recompile the library in debug mode, even if you don't intend to debug the library itself.

pic11
  • 14,267
  • 21
  • 83
  • 119
  • Thanks. So the problem has nothing to do with release build library linking with debug build project. I don't have any idea what this iterator debugging is about, and i can't seem to find a way to change the iterator debug mode in VS2010. However i did some searching and found that if i put #define _HAS_ITERATOR_DEBUGGING 0 in my code, then it works. I can run my project in debug with the release library. Although I don't really understand what's going on. – terryhau Apr 24 '11 at 17:42
  • @terryhau the _HAS_ITERATOR_DEBUGGING macro controls a lot of framework that the visual compiler puts in place to help you debug iterators. With level 2, it provides iterator out of bounds access check, and a lot of very neat debugging stuff. Take a look on [channel9](http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Advanced-STL-3-of-n) if you want more details. – wendazhou Apr 24 '11 at 18:06
  • @Razispio Thanks. I'll have a look. I'm just wondering, since i compiled the library in release mode, shouldn't all the iterator debugging stuff be disabled or removed? – terryhau Apr 24 '11 at 18:19
  • @terryhau. _HAS_ITERATOR_DEBUGGING must be set in every implementation file (.cpp or .cc files) before you include anything from STL. The safest method is to add D_HAS_ITERATOR_DEBUGGING=0 to compiler command line options. Right click your project and click on Properties--> C++ --> Command line options (or something like that, can't recall exactly). – pic11 Apr 24 '11 at 18:35