Context: In this answer , I learned that gcc's __builtin_unreachable()
can have some surprisingly impactful performance implications, as it seems that the following:
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.
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:
// 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()
. 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.
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:
Test Cases AND assertion statements
Your macro silently breaks the exception-part for release builds.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.