C++11 formalized the notion of a narrowing conversion, and disallowed using one at the top level in list-initialization.
I am wondering whether, given two types T
and U
, it is possible for it to be implementation-defined whether a conversion from T
to U
is narrowing. According to my reading of the standard, this is the case. Here is my reasoning:
unsigned int
to long
.int
and long
, C++ requires only that sizeof(int) <= sizeof(long)
.sizeof(int) == sizeof(long)
. On this implementation, long
cannot represent all the values of unsigned int
, so the conversion would be narrowing.sizeof(int) < sizeof(long)
. On this implementation, long
can represent all the values of unsigned int
, so the conversion would not be narrowing.Am I correct in my analysis that it can be implementation-defined whether a conversion is narrowing? Is this desirable?
I would indeed prefer the "narrowing conversion" to be defined on the types itself. In a way so that int i{long(non_constant_expression)}
is never allowed to compile. The simple reason is: Either you don't need the long range, then you should use int
in the first place, or you really want the "cut", which seems like a rare enough case for me to require an explicit type conversion or a cast. To answer the first question: It is implementation defined.
But to be honest, I almost never use this raw types, just size_t
, int32_t
, uint16_t
etc., and this solves the problem automatically. (uint16_t {uint8_t()}
is always narrowing, uint16_t{uint16_t()}
never.) One just has to thoughtfully convert size_t
into something else, but that is always the case.
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