有没有理由不在一个解析为gcc中的__builtin_unreachable()的宏中包装assert()?

时间:2017-09-11 07:53:16

标签: c++ gcc optimization assert

背景:在这个answer中,我了解到gcc的__builtin_unreachable()可能会产生一些令人惊讶的影响性能影响,因为它似乎如下:

if(condition) __builtin_unreachable();

被完全剥离,只要condition可以保证不会产生任何副作用,就可以用作优化提示。

所以我对此的直接反应是我应该创建以下宏,并且在我通常使用assert()的任何地方绝对使用它,因为assert()内的副作用诱导代码将是一个主要的首先是错误:

// TODO: add handling of other compilers as appropriate.
#if defined(__GNUC__) && defined(NDEBUG)
  #define my_assert(condition) \
    if(!(condition)) __builtin_unreachable()
#else 
  #define my_assert(condition) assert(condition)
#endif

从标准的角度来看,这会在普通版本和NDEBUG版本之间创建功能分割,您可以将参数排除在外,将此宏排除在assert()的标准行为之外。但是,由于在断言失败的情况下,我的代码在功能上会死在水中,从行为的角度来看,它完全等同。

所以我的问题是:任何人都可以想到不这样做的理由(来自涉及大量间接的断言)?

在你问之前,是的,我已经检查过gcc的行为是否使NDEBUG版本中的断言失效。

1 个答案:

答案 0 :(得分:2)

是的,有理由不使用它。 有些人使用以下防御代码实践,结合断言和异常(assert(x>0); if (!(x<0)) throw std::logic_error("..")) - 请参阅此答案:

Test Cases AND assertion statements

你的宏默默地打破了发布版本的异常部分。