其他分享
首页 > 其他分享> > c – 使用调试断言时避免ODR违规

c – 使用调试断言时避免ODR违规

作者:互联网

我有一个只有头的库,在调试模式下编译时启用了一些额外的失败快速运行时断言.标头的简化版本如下所示:

#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;
    }
};

如果一个翻译单元包括标题而没有首先定义MYDEBUG,而另一个翻译单元在定义MYDEBUG之后包含它,并且我将结果对象文件链接在一起,那是否会构成ODR违规?

如何避免这种情况但仍然允许每个TU在包含标题时独立指定其所需的断言设置?

解决方法:

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?

处理的一种方法是将MYASSERT定义为文件范围的静态函数.

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

看来你做不到.谢谢,@ RustyX.

标签:one-definition-rule,c
来源: https://codeday.me/bug/20190828/1748820.html