Search code examples
c++c++11list-initialization

Why does list initialization allow conversion from double to float values?


List initialization (the {...} syntax) doesn't allow narrowing conversions. For example, trying to list-initialize an int i with 3.14f holds a compilation error, as conversion from floating point values to integers is narrowing:

<source>:11:32: error: narrowing conversion of '3.1400001e+0f' from 'float' to 'int' inside { } [-Wnarrowing]
     int i{3.14f};
                ^

With that said, why is it possible to construct a float f with 3.14, which is of type double? (Conversion from double to float is considered a narrowing one.) Doing the following:

float f{3.14};

Holds no compilation errors.


Solution

  • In the list of what is considered a narrowing conversion, constant expressions that fit within the target type are an exception. So while in general double to float is narrowing, when your double is actually a literal this is permitted.

    http://coliru.stacked-crooked.com/a/6949f04fa4a8df17


    From the draft I have on hand (I think close to C++14):

    8.5.4 List-initialization
    (7.2) A narrowing conversion is an implicit conversion...
    ...from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly),