-
Notifications
You must be signed in to change notification settings - Fork 2.1k
core/assert: mark failed condition unreachable with NDEBUG #19337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
5633326
to
3ce4cec
Compare
175c819
to
d633d82
Compare
bors try |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other than these new inlines 👍
since this change core it needs 2nd ack
sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c
Outdated
Show resolved
Hide resolved
Making the functions But I can drop it. |
maybe @miri64 or @kaspar030 wants to a (second) look |
This is somewhat similar to #16375 (before the drop of void foo(int bar)
{
#NDEBUG
(void)bar
#endif
assert(bar == 42); boilerplate this also improves the binaries. I'm in favor of this. It does change the semantics of assert(spi_acquire(...) == SPI_OK); to still work with We do no longer have a cppcheck pass that would prevent statements with side-effects in |
If you add a bit of documentation that explains how our I think something such as #define LOG_DEBUG(...) assert(printf(__VA_ARGS__) > 0) would be actually legitimate, but insane. But I cannot come up with code that is sane and bug-free that would notice the deviation from the C standard here. |
I extended the documentation in |
86e58b0
to
c9bd3df
Compare
c9bd3df
to
36a34e5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This version of
assert()
slightly deviates from the one described in the standard
That's a gross understatement. This change turns code that's well-defined in C (eg. int f(int i) { assert(i != 0); return 2 * i; }
/ f(0)
) to never be undefined behavior into undefined behavior.
I haven't manage to read all comments yet in the short time since I've seen this, but I'd advocate we use a dedicated function (dunno, maybe assume()
) instead of redefining something that's well known to C programmers.
Wouldn't this change also introduce additional if statements for productive code? |
It might introduce additional statements; as long as the assert is simple, it typically won't (because the unreachable will just narrow down the legal values), but if the assert includes a call outside the current compilation unit, that call suddenly will be made. |
In my perception |
Assumption about generated code and the C language don't mix well together. The C compiler is allowed to do crazy things like taking the hash value of the source file as seed for a random number generator that is used for statistical analysis (e.g. which code path is taken more often 200 randomly chosen inputs) and optimize for that. Fixing a typo in a comment would then result in possibly better or worse machine code (in terms of code size, performance). Both versions would however be show the same observable behavior and, thus, would be correct. |
Unless it's part of a specification. The POSIX doc says: The Linux man page for instance states: |
superseded by merged #19354 |
Contribution description
The compiler is pretty smart about optimizing code when it knows that a condition can not happen.
When
DEVELHELP
is enabled it knows that the condition inside theassert()
must be always true and can optimize the code accordingly, as otherwise a__NORETURN _assert_failure()
function is called.With
DEVELHELP
disabled the compiler no longer has this information because theassert(cond)
is replaced by a(void)cond
by the preprocessor.Replace it by a
if (!cond) { __builtin_unreachable(); }
instead.Testing procedure
Code size decrease shows the compiler can optimize the code with
DEVELHELP=0
:master
this PR
see also https://godbolt.org/z/KaajqWv5Y
and https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1774r4.pdf
Issues/PRs references