简体   繁体   中英

What does the C++ standard say about results of casting value of a type that lies outside the range of the target type?

Recently I had to perform some data type conversions from float to 16 bit integer. Essentially my code reduces to the following

float f_val = 99999.0;
short int si_val = static_cast<short int>(f_val);

// si_val is now -32768

This input value was a problem and in my code I had neglected to check the limits of the float value so I can see my fault, but it made me wonder about the exact rules of the language when one has to do this kind of ungainly cast. I was slightly surprised to find that value of the cast was -32768. Furthermore, this is the value I get whenever the value of the float exceeds the limits of a 16 bit integer. I have googled this but found a surprising lack of detailed info about it. The best I could find was the following from cplusplus.com

Converting to int from some smaller integer type, or to double from float is known as promotion, and is guaranteed to produce the exact same value in the destination type. Other conversions between arithmetic types may not always be able to represent the same value exactly:

 If the conversion is from a floating-point type to an integer type, the value is truncated (the decimal part is removed). The conversions from/to bool consider false equivalent to zero (for numeric types) and to null pointer (for pointer types); and true equivalent to all other values. Otherwise, when the destination type cannot represent the value, the conversion is valid between numerical types, but the value is implementation-specific (and may not be portable). 

This suggestion that the results are implementation defined does not surprise me, but I have heard that cplusplus.com is not always reliable.

Finally, when performing the same cast from a 32 bit integer to 16 bit integer (again with a value outisde of 16 bit range) I saw results clearly indicating integer overflow. Although I was not surprised by this it has added to my confusion due to the inconsistency with the cast from float type.

I have no access to the C++ standard, but a lot of C++ people here do so I was wondering what the standard says on this issue? Just for completeness, I am using g++ version 4.6.3.

You're right to question what you've read. The conversion has no defined behaviour, which contradicts what you quoted in your question.

4.9 Floating-integral conversions [conv.fpint]

1 A prvalue of a floating point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type. [ Note: If the destination type is bool , see 4.12. -- end note ]

One potentially useful permitted result that you might get is a crash.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM