Consider this code:
void foo(int n) {
assert(n>=0&&n<=3);
for (int i=0; i<n; i++) {
doSomething();
}
}
Here, there is an assert: n
is between [0;3]. Asserts generally used for checking programmer mistakes. But here, it could be used as a hint to the compiler that n
is between [0;3], so it could optimize better. Maybe it can unroll the loop, and use a jump.
For GCC, we can help the compiler manually:
if (!(n>=0&&n<=3)) __builtin_unreachable();
Here, GCC was actually informed that n is between [0;3], so it could generate better code.
My question is: is it possible to create a (possibly compiler dependent) new_assert
macro, which can tell hints to the compiler in release builds? This solution must be transparent, so it can be a full replacement for the assert
macro. For example, in "new_assert(func());
" func()
must not be called in release builds, if it has side effects.
Or, if it is not possible, another useful new_assert
could be, if the condition is not allowed to have side effects (it would cause compile-time error), so we can use if (!(cond)) __builtin_unreachable();
in release builds without the fear that cond
has a side effect. I.e. is it possible to create a new_assert
that is checked whether its condition has side effects?
This is a related question.
This is a very similar question, but this time I ask whether it is possible to create a full replacement for the assert
macro (so we can avoid manually annotating code)
Answer: An assert in C++ is a predefined macro using which we can test certain assumptions that are set in the program. When the conditional expression in an assert statement is set to true, the program continues normally. But when the expression is false, an error message is issued and the program is terminated.
In the C Programming Language, assert is a macro that is designed to be used like a function. It checks the value of an expression that we expect to be true under normal circumstances. If expression is a nonzero value, the assert macro does nothing.
Turning on optimization flags makes the compiler attempt to improve the performance and/or code size at the expense of compilation time and possibly the ability to debug the program. The compiler performs optimization based on the knowledge it has of the program.
gcc (with the -finline-functions option) and a few other compilers are capable of inlining small functions at higher optimization levels automatically.
I reckon that if you just add undefined behavior in the new_assert() macro, the compiler will decide that those preconditions are non-negotiable. and generate faster code.
However, if your code is buggy, and the assert fails, anything could happen.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With