HighCommander4
HighCommander4

Reputation: 52759

Implementation-defined narrowing conversions?

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:

Am I correct in my analysis that it can be implementation-defined whether a conversion is narrowing? Is this desirable?

Upvotes: 12

Views: 10680

Answers (2)

Valerian Ardelean
Valerian Ardelean

Reputation: 406

În my case, for this piece of code: char *pointer = strchr(s1, s2[I]); int start = pointer - s1; It worked to change the int data type to long: long start = pointer - s1;

"The compiler cannot determine how large or small a value is for a specific data type; therefore, the compiler cannot determine if the specified value fits in the new field that you assign it to. If you are sure that there is no overflow, explicitly type cast the value to avoid the warning." - source : https://www.ibm.com/docs/en/ztpf/2020?topic=warnings-narrowing-conversion

Upvotes: 0

cooky451
cooky451

Reputation: 3510

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.

Upvotes: 5

Related Questions