Why gcc warns about narrowing conversion only for uniform initialization?

血红的双手。 提交于 2020-08-15 05:42:08

问题


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 };

回答1:


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.




回答2:


The difference between the two is that narrowing conversions are not allowed in a list initialization. In other forms of initialization they are allowed.

The thing that often confuses people here is that when something is not allowed it doesn't mean that the compiler must refuse to compile the code. The requirement is that the compiler must "issue a diagnostic", and a warning is a valid form of diagnostic.

So the compiler is required to issue a diagnostic for a narrowing conversion in a list initialization, and that's what you're seeing. Beyond that, as others have said, you can crank up the warning level to get warnings about narrowing conversions in other contexts. But outside of list initialization diagnostics are not required, and they're often more annoying than useful, so not turned on by default.



来源:https://stackoverflow.com/questions/51497097/why-gcc-warns-about-narrowing-conversion-only-for-uniform-initialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!