问题
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