gcc provides additional builtin functions "for optimization".
One of them is void __builtin_trap (void)
which essentially is here to abort the program by executing an illegal command.
From the doc:
__builtin_trap function causes the program to exit abnormally. GCC implements this function by using a target-dependent mechanism (such as intentionally executing an illegal instruction) or by calling abort. The mechanism used may vary from release to release so you should not rely on any particular implementation.
Why would you ever use this rather than exit(1)
or abort
? Why did the gcc developers see this as an optimization function?
int__builtin_ffs (unsigned int x) Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero. int__builtin_clz (unsigned int x) Returns the number of leading 0-bits in x, starting at the most significant bit position. If x is 0, the result is undefined.
GCC provides built-in versions of the ISO C99 floating-point comparison macros that avoid raising exceptions for unordered operands. They have the same names as the standard macros ( isgreater , isgreaterequal , isless , islessequal , islessgreater , and isunordered ) , with __builtin_ prefixed.
Because exit(1)
causes the program to terminate normally with an error status code. See the cppreference page. In contrast __builtin_trap
causes the program to terminate abnormally.
The simplest way to see the differences is to look at the guarantees made by exit
, if doing one of those things is something you don't want to happen, __builtin_trap
would be better.
Debugging is the most common example, as __builtin_trap
could trigger a debugger to dump the process, while exit
would not (since the program terminates "normally" with an error).
The __builtin
functions are not necessarily for optimisation - they are for "doing things that the compiler can't do directly from source code", including support for "special instructions" and "architecture-specific operations". One of the main purposes of __builtin
functions is that the compiler will "know" what these do at a later stage. Although there are "library optimisations" in the compiler, the compiler can use __builtin
functions much more freely to determine that the behaviour is something specific - for example, __builtin_trap
can be relied upon to "not continue to the next instruction", so the compiler doesn't have to worry about code like:
if (x <= 0.0) __builtin_trap();
y = ln(x);
It can then make use of the "fast inline version of ln
", since the error has been caught already.
Note also that __builtin_trap
is almost guaranteed to end up as a "stop" in the debugger, where exit(1)
or some such will just exit the program with a "not success" result code, which is rather annoying if you are trying to figure out where that math error message came from...
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