背景:在这个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
版本中的断言失效。
答案 0 :(得分:2)
是的,有理由不使用它。
有些人使用以下防御代码实践,结合断言和异常(assert(x>0); if (!(x<0)) throw std::logic_error("..")
) - 请参阅此答案:
Test Cases AND assertion statements
你的宏默默地打破了发布版本的异常部分。