For 10.0 specifically, double is more than large enough to, as far as I know, result in the same output. For arbitrary double literals, I wouldn't expect this to be the case.
Note: overflow cast from double to int is undefined, last I looked, so one could argue that the numerical regions for which quantization would occur are outside of the practical range of this chunk of code.
#include <limits.h>
int N;
int fn5(int p1, int p2) {
int a = p2;
if (N && INT_MIN / 10.0 <= a && a <= INT_MAX / 10.0)
a *= 10.0;
return a;
}
GCC still does the multiplication as double, Clang still does it as int.(And both evaluate the guards as int, so there.)
A) fraught with edge-case peril
and
B) easily accounted for by the developer (e.g. write "a *= 10;")...
I don't think I understand what you mean. Can you give an example?
As for "the developer should write what they mean", one standard answer from compiler developers is along the lines of "but this code might not be hand-written, it might come from a primitive code generator". You can decide whether that convinces you or not ;-)
An example number might be 8388608.0 (or 2^23). Hell could have broken out more than four million integer values before that, but it's as nice a test as any (except maybe the exact edge).
There could also be interesting cases of compound arithmetic literal statements. And then, of course, there are other side-effect considerations (e.g. the x87 opcode register).
I'll stick to getting my literal types right in the first place, but, as stated above, it doesn't feel like a real miss to me. Either a dev or a code generator wrote ".0". I'm inclined to respect that to some degree.
Probably because I'm old.
I'll compile this in gcc and clang and see what shakes out. My bet is that clang does the right thing once the value is out of safe range.