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?
If one translation unit includes the header without defining
MYDEBUGfirst, and another one includes it after definingMYDEBUG, 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With