A narrowing conversion changes a value to a data type that might not be able to hold some of the possible values. For example, a fractional value is rounded when it is converted to an integral type, and a numeric type being converted to Boolean is reduced to either True or False .
If you make a narrowing conversion intentionally, make your intentions explicit by using a static cast. Otherwise, this error message almost always indicates you have a bug in your code. You can fix it by making sure the objects you initialize have types that are large enough to handle the inputs.
Is the following code legal in C++11?
int16_t x {0xaabb};
int64_t xxxx {0xaaaabbbbccccdddd};
The code is from "The C++ Programming Language" 4th edition (page 150).
As we know, narrowing conversion is not allowed for list initialization, and among the standard's definition of narrowing conversion, we have:
A narrowing conversion is an implicit conversion
— [...]
— from an integer type or unscoped enumeration type to an integer type that cannot represent all the values of the original type, except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type.
Checking the rule of narrowing conversion against the sample code, I justify that the sample code is illegal because 0xaabb
and 0xaaaabbbbccccdddd
cannot be represented in int16_t
and int64_t
respectively. Is that correct?
But I don't quite understand the wording "except where the source is a constant expression and the actual value after conversion will fit into the target type and will produce the original value when converted back to the original type". I wonder in what scenario the actual value after conversion cannot fit into the target type. Since conversions between integer types are always valid (though implementation-defined in the case where the destination type is signed and the source value cannot be represented in the destination type, but it's not undefined behaviour anyway), is it always true that "the value after conversion will fit into the target type"? And from this point of view, I'm starting to question my judgement of the sample code being narrowing conversion. If that is the case, why does the standard put something always true in a condition? Why not just say "except where the source is a constant expression and the actual value after conversion will produce the original value when converted back to the original type"?
Can someone help me clarify this? Thank you!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With