c++c++11language-lawyercompiler-warningsuniform-initialization

Why gcc warns about narrowing conversion only for uniform initialization?


I am trying to convert long type variable to int type variable with uniform initialization and without it. But I get compiler warning only with uniform initialization. Why is that? Why does not gcc warn in both cases? I have tried with clang also and got similar results.

This is the code

#include <iostream>

int main() {
    long l = 1;
    int i1 = l;
    int i2 = { l };

    std::cout << i1 << std::endl;
    std::cout << i2 << std::endl;

    return 0;
}

And the only one warning I get

$ g++ -Wall -Wextra 1.cpp
1.cpp: In function ‘int main()’:
1.cpp:6:16: warning: narrowing conversion of ‘l’ from ‘long int’ to ‘int’ inside { } [-Wnarrowing]
   int i2 = { l };

Solution

  • Because the standard says, narrowing conversions limit is specified only for list initialization (since C++11).

    list-initialization limits the allowed implicit conversions by prohibiting the following:

    • conversion from a floating-point type to an integer type
    • conversion from a long double to double or to float and conversion from double to float, except where the source is a constant expression and overflow does not occur
    • conversion from an integer type to a floating-point type, except where the source is a constant expression whose value can be stored exactly in the target type
    • conversion from integer or unscoped enumeration type to integer type that cannot represent all values of the original, except where source is a constant expression whose value can be stored exactly in the target type

    For the other initialization methods (using parentheses or equal sign), narrowing conversions limit rule is not applied (added); because that might break much legacy code.