CBFalconer said:
So, by eliminating the possibility, you eliminate the complaint.
I'm not sure which possibility you're referring to. I'm not sure which
complaint you're referring to.
... snip ...
Floating point is ALWAYS an approximation.
Agreed - which is why I said "such code should not be written in the
first place".
.. You can never assume
the value is exact.
That depends upon the values involved, the code, and the implementation.
On most implementations I'm familiar with, sufficiently small integer
values (and "sufficiently small" includes some very large numbers)
divided by powers of 2.0 (negative powers included) can be relied upon
to be stored and compared exactly, assuming the number is within range
of the floating point type used. Also, if you do nothing with a floating
point value but move it around from one variable to another of the same
or greater precision, you can rely upon that value to be unchanged by
movement, and to compare to it's original value.
None of that's guaranteed by the standard, but I know of no reason why
it couldn't be; and it's sufficient to make exact comparison of floating
point values a reasonable thing to do, under some circumstances. Those
circumstances are sufficiently tricky to identify that it's a bad idea
to take advantage of them. That's the real reason why floating point
values should not be allowed as controlling expressions in switch()
statements. The feasibility (or lack thereof) of using a jump table to
implement such switch() statements is irrelevant, because there's no
need to use jump tables.
... For a case table you need exact values. Thus
to have the option of a case table you need exact values.
Yes, but there's no need to generate a case table from a switch
statement; it's always possible to implement it as a chain of if-else
statements. Allowing floating point values to be used as a controlling
expression would do nothing to prevent generation of a case table when a
program contains a switch statement with a controlling expression of
integer type.
In addition, conversion between float and integer is not trivial.
Neither is it rocket science. However, since there's no need to generate
case tables, an implementation that doesn't want to be bothered with
such a conversion need not even bother checking for the possibility that
a case table would be a legal way to implement a switch() statement, if
setting one up would require performing such a conversion.
Note: if the controlling expression of a switch() statement were allowed
to have a floating point type, and the values of the case expressions
happened to be such that they allowed efficient use of a jump table,
then the code generated by the compiler could NOT be equivalent to the
code you presented which I've quoted at the top of this message. That is
because doing so would produce incorrect behavior when the controlling
expression is not exactly equal to one of the case expressions, as
discussed above.
It would have to do something like the following (note that the goto
statements below are not proper C code; they are merely symbolic of what
the generated code does):
if(float_value >= min_case && float_value <= max_case)
{
int index = (int)floor((float_value - offset) / scale);
if(index * scale + offset == float_value)
goto jump_table[index];
}
goto default case;