Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding ODR violations when using debug asserts

I have a header-only library that has some additional fail-fast runtime assertions enabled when compiled in debug mode. A simplified version of the header looks like this:

#include <exception>

#ifdef MYDEBUG
#   define MYASSERT(condition) do{ if (!(condition)) std::terminate(); } while(0)
#else
#   define MYASSERT(condition)
#endif

template<typename T>
class Checker
{
public:

    T operator()(T value)
    {
        MYASSERT(value);
        return value;
    }
};

If one translation unit includes the header without defining MYDEBUG first, and another one includes it after defining MYDEBUG, and I link the resultant object files together, would that constitute an ODR violation?

How can I avoid this but still allow each TU to independently specify its desired assertion settings when including the header?

like image 664
TripShock Avatar asked Jun 23 '26 12:06

TripShock


1 Answers

If one translation unit includes the header without defining MYDEBUG first, and another one includes it after defining MYDEBUG, and I link the resultant object files together, would that constitute an ODR violation?

Yes, it is a violations of the one-definition-rule. It's a violation of the rule for inline functions that says the inline function definitions must have the exact tokens in all the translation units.

How can I avoid this but still allow each TU to independently specify its desired assertion settings when including the header?

One way to deal with is to define MYASSERT to be file scoped static functions.

#ifdef MYDEBUG
static void MYASSERT(bool condition)
{
   if (!(condition))
   {
      std::terminate();
   }
}
#else
static void MYASSERT(bool condition)
{
   // Noop
}
#endif

It appears that you cannot. Thanks, @RustyX.

like image 186
R Sahu Avatar answered Jun 26 '26 04:06

R Sahu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!