C introduced the concept of a single errno
or "error number" that could be used to determine the precise cause of the failure of some standard functions, including mathematical functions, to perform their duties. POSIX extended errno
, and C++11 picked up some of those extensions too.
When one of these functions fails, the global integer errno
is set to a value that tells you why. Obviously that incurs a performance penalty.
GCC is saying that this flag disables this behaviour for certain mathematical functions, speeding up your program at the cost of diagnostic utility and standard-compliance.
If you're already not observing errno
when any of the affected functions fails, and you're probably not because you'd never heard of it, then you won't lose any functionality. This may be the case if you're writing a really time-constrained program, or when the particular reason for a failure doesn't dictate what your code does next. (However I advise looking into error checking more broadly to ensure that your code is as robust as it ought to be.)
However, it is possible for you to accidentally observe side-effects if you have a bug. Imagine if you were doing something like the following:
std::some_maths_function(42);
if (errno == ERANGE)
exit(-1);
Oops! We are checking errno
even when some_maths_function(42)
succeeded. Let's say that above this code is a call to std::some_other_maths_function(999)
which usually fails and results in errno
being set to EDOM
. That masked the bug in the code above.
Now turn on the compiler flag. If some_other_maths_function
is one of the functions that no longer sets errno
, your bug will be unmasked, and it may take you a few moments to realise that you ought to have written something more like:
if (std::some_maths_function(42) == -1)
{
if (errno == RANGE)
exit(-1);
}
Of course it's hardly GCC's fault that you had a bug, but this does show how the behaviour of your program can differ after enabling this "optimisation" flag. Indeed, the documentation says:
This option is not turned on by any -O option since it can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.
In other words, this flag sends you off-book. But it may be worth it.
The variable errno
must be thread-local (that is, there is actually one of them for each thread in your program) otherwise it'd be useless in a multi-threaded program. You can research the term "thread-local" for more information on this subject.