Re: Test for NaNs?
* Gabriel Dos Reis:
"Alf P. Steinbach" <alfps@start.no> writes:
| * Gabriel Dos Reis:
| > "Alf P. Steinbach" <alfps@start.no> writes:
| >
| > | Not very long ago there was anoher clc++m thread about NaN detection where I
| > | proposed x==x, and Someone Else pointed out that even g++ (IIRC) gets that
wrong
| > | when the right, or wrong :-), kind of optimization is turned on.
| >
| > GCC indeed has switches that tell the compiler to assume that some
| > kinds of floating point singularities are absent from the program.
| > There is nothing surprising in that.
|
| It surprised me that the compiler reports being IEEE 754 standard-conforming,
| via is_iec559, and isn't.
unhelpful oversimplification/distorsion.
With the appropriate switch (e.g. -ffinite-math-only), the user can
instruct the compiler has to trust him/her that there is no floating
point infelicities in your program. Consequently, the compiler is free to
optimize the input program accordingly. That the user thinks the
compiler is lying to him/her might actually be a consequence of a
reflection law where user is lying to the compiler.
Consider a function that, if std::numeric_limits<double>::is_iec559, returns
NaN, and otherwise throws an exception, where this function plus a call of it
with checking of NaN or not is the only handling of 'double' in the program.
For a C++ standard-conforming compiler it would not be lying to the compiler to
use an option that says it's OK to change the semantics of 'double' so that the
type no longer has quiet NaN (no longer has the behavior required of quiet NaN).
For if the compiler is C++ standard-conforming, with that option
std::numeric_limits::has_quiet_NaN would have to be false, and since the C++
standard requires that has_quiet_NaN is true if is_iec559 is true, with that
option turned on is_iec559 must also be false, hence, with that option turned on
the code will not rely on NaN semantics, as the user has promised.
This can only fail if the compiler lies, if it in spite of not implementing
quiet NaN sets std::numeric_limits<double>::is_iec559 to true (which per the C++
standard requires has_quiet_NaN, which requires having quiet NaN).
And in fact at least two compilers lie, and reportedly this is very common.
But, I suspect
the user already figured that part out by reading the fine manual.
-ffinite-math-only
Allow optimizations for floating-point arithmetic that assume that
arguments and results are not NaNs or +-Infs.
This option is not turned on by any -O option since it can result
in incorrect output for programs which 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.
The default is -fno-finite-math-only.
If I understand it correctly, you're maintaining that a common compiler behavior
where std::numeric_limits offers incorrect information, is nothing remarkable.
According to the above, if it changes the semantics and effect of library code,
it's the user's fault for not intuiting that std::numeric_limits would not
reflect the semantics chosen by some compiler option, and so it isn't a problem
for e.g. library code because the user can just refrain from using that option,
or, where it's the default for the compiler, turn it off in some way.
Consider the following program:
<code>
#include <iostream>
#include <limits>
int main( int n, char** )
{
using namespace std;
bool const falze = n < 0;
char const c = (falze? 0 : char(-1));
bool const ok = ((c < 0) == numeric_limits<char>::is_signed);
cout << (ok? "OK" : "Lie") << endl;
}
</code>
Explanation: it tests whether the actual signedness of type 'char' is the same
as reported by std::numeric_limits, and it uses a dependency on program
arguments to avoid folding of expressions at compile time.
Would you really argue that, if this program outputs "Lie"[1], it's the user's
fault for not intuiting the hidden C++ standard-breaking meaning of the
documentation of some semantics-affecting option (with g++, the option
"-funsigned-char" and with MSVC "/J")?
And if you wouldn't argue that it's the user's fault in the case of
std::numeric_limits::is_signed, why are you arguing that it's the user's fault
for the case of std::numeric_limits::is_iec559?
Cheers, & eagerly awaiting your clarification,
- Alf
Notes:
[1] For the record, neither of the two compilers mentioned outputs "Lie" for
this program, testing is_signed, regardless of the options mentioned above.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]