Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent mixing debug and release libraries

Tags:

c++

visual-c++

As a library developer, I want to prevent my library users (Windows, MSVC) from linking to the wrong configuration (not to link the debug library to their release programs, and vice versa).

Is it possible to warn the user during compile time that (s)he should link to the right configuration of the library ?

EDIT

Both debug and release versions should be available to allow Windows developers to debug their applications. So both debug and release versions of my library should be available.

I am asking this question because lot of the support to Windows beginner developers is caused by them mixing debug and release code, and getting difficult-to-debug runtime errors.

like image 367
Mourad Avatar asked Oct 12 '11 08:10

Mourad


2 Answers

Good question, I've always assumed that developers using my libraries would link to the correct version. Now that I think about it, why would you even want to release your debug library to the public? Why shouldn't both their debug and release versions link against your release library?

Regardless, I see a way of doing this by exporting some symbols per configuration:

//header:
class DLLIMPEXP Dummy
{
   static int x;
   virtual void dummy();
}
//cpp
#ifdef DEBUG
int Dummy::x = 0;
void Dummy::dummy()
{
}
#endif

As you can see, your symbol will only be exported if your module is compiled in DEBUG. Trying to link against the lib in release mode from a third module would result in a linker error. You can have something similar for the reverse case.

I don't suggest you do this though, I would rather document it or only distribute the release version of my module.

like image 188
Luchian Grigore Avatar answered Oct 04 '22 22:10

Luchian Grigore


There are two different aspects here:

  • incompatibility issue
  • performance issue

If it is a matter of performance, then the choice should still be theirs, they might wish to debug.

If it is a matter of incompatibility, one simple thing is to change the namespace for the debug version, so that symbols are mangled differently.

#ifdef NDEBUG
  namespace project {
#else
  namespace project { namespace debug {
#endif

// content

#ifdef NDEBUG
  }
#else
  }
  using namespace debug;
  }
#endif

By nesting in a debug namespace, you change the mangling of the symbols (even though, compilation-wise, it does not change anything). This actually prevent linking a library compiled against the debug version with the release version (and thus solves the incompatibility early on rather than crashing mysteriously).

However, I would urge you to reserve this to a very specific set of classes (it's heavy).

It should be possible, normally, to be able to provide compatible interfaces in both the Debug and Release modes, so that clients can hot-swap at load time.

like image 23
Matthieu M. Avatar answered Oct 04 '22 22:10

Matthieu M.