简体   繁体   English

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

[英]Is there any reason not to wrap assert() in a macro that resolves to __builtin_unreachable() in gcc?

Context: In this answer , I learned that gcc's __builtin_unreachable() can have some surprisingly impactful performance implications, as it seems that the following: 上下文:在这个答案中 ,我了解到gcc的__builtin_unreachable()可能会产生一些令人惊讶的性能影响,因为它似乎如下:

if(condition) __builtin_unreachable();

is being entirely stripped, and used as an optimization hint as long as condition can be guaranteed to not have any side effect. 被完全剥离,并且只要condition可以保证没有任何副作用,就可以用作优化提示。

So my immediate reaction to this is that I should create the following macro, and use it absolutely everywhere I would normally use assert() , since side-effect inducing code inside an assert() would be a major bug in the first place: 所以我对此的直接反应是我应该创建下面的宏,并且在我通常使用assert()地方绝对使用它,因为在assert()的副作用导致代码首先是一个主要的bug:

// 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

From a standards perspective, this would create a split in functionality between normal and NDEBUG builds, which you could make an argument excludes this macro from being the standard behavior of assert() . 从标准的角度来看,这会在普通和NDEBUG构建之间创建一个功能分离,你可以使一个参数将这个宏排除在assert()的标准行为之外。 However, since my code would be functionally dead in the water in the case of assertion failures regardless, it's fully equivalent from a behavioral standpoint. 但是,由于我的代码在断言失败的情况下在功能上会死在水中,因此从行为的角度来看,它完全等同。

So my question is: Can anyone think of a reason not to do this (appart from asserts that involve a lot of indirections)? 所以我的问题是:任何人都可以想到不这样做的理由(来自涉及大量间接的断言)吗?

Before you ask, yes, I've checked that gcc's behavior is to void cast the assertion away in NDEBUG builds. 在你问之前,是的,我已经检查过gcc的行为是否在NDEBUG版本中将断言转换为无效。

Yes, there is a reason to not use it. 是的,有理由不使用它。 Some people use the following defensive code practice that combines assert and exception ( assert(x>0); if (!(x<0)) throw std::logic_error("..") ) - see this answer: 有些人使用以下防御性代码实践,它结合了assert和exception( assert(x>0); if (!(x<0)) throw std::logic_error("..") ) - 看到这个答案:

Test Cases AND assertion statements 测试用例和断言陈述

Your macro silently breaks the exception-part for release builds. 您的宏默默地打破了发布版本的异常部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM