Two things every C++ tutorial mentions early on:
- Braced initialization is generally superior when possible, because it will throw an error during a narrowing conversion such as
int narrow{1.7}; // error: narrowing conversion of '1.7e+0' from 'double' to 'int'
- You must explicitly declare floats as float literals, otherwise they will default to double literals
float some_float{1.7f};
However, when working with the g++ compiler on Windows, I've discovered something odd -
float narrow{1.7}; // still a float despite no f postfix
double not_narrow{1.7}; // actually a double
This code compiles without any errors, and sizeof(narrow) returns 4, where sizeof(not_narrow) returns 8, as expected.
Hovering over 1.7, VSCode identifies it as a double literal ~=1.699999999999999956, but float has then narrowed it to ~=1.700000048.
I thought it might be simply that 1.7 is both valid as a float and a double, so I tried
float narrow{1.699999999999999956};
but this produces an identical result.
Why doesn't braced initialization throw an error (warning, diagnostic message, anything) here for narrowing a double literal to a float? Is this g++ specific, or a quirk of C++ in general? I'd love to understand better.