Otherwise, the new type is signed and the value cannot be represented in it either the result is implementation-defined or an implementation-defined signal is raised. When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged. This is what the C99 standard has to say about it: In the previous example, a larger signed type is converted into a smaller signed type. This surely overflows, doesn’t it? Doesn’t this yield undefined behavior? The answer in this case is a clear ‘no’. For instance, these asserts will hold on many platforms:Īdding two integers that hold a value of SHRT_MAX doesn’t overflow, unless - and that’s why it depends - you are hacking away on an ancient 16-bit platform where sizeof(short) = sizeof(int).īut even on a typical 32- or 64-bit platform, what about the assignment of the large integer result to the short variable sum. You might have believed (and observed) that in C signed integers also wrap around. To sum it up: on overflow, unsigned integers wrap-around whereas signed integers “overflow” into the realm of undefined behavior (contrary to Java and C#, BTW, where signed integers are guaranteed to wrap around). J.2 Undefined behavior: The value of the result of an integer arithmetic or conversion function cannot be represented. There are, however, various hints in the standard that signed integer overflow is undefined, for instance:ģ.4.3 Undefined Behavior: An example of undefined behavior is the behavior on integer overflow. Nothing is explicitly said about signed integer types. Thus, unsigned integer overflow is well defined and not called overflow by the language standard.Ģ. Unsigned integer types wrap-around on overflow, “reduced modulo the number that is one greater than the largest value” is just a fancy name for it. C-overflow is more like an error condition that occurs if overflow behavior is not defined for a type.ġ. Apparently, there is overflow (as defined above) and C-overflow (as used by the standard). “A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type”Ġ. If you want to find out how C (and C++) handles integer overflow, you have to take a look at chapter 6.7.5 “Types”, the following sentence in particular: Other possibilities exist, ranging from saturation (the overflowing value is set to the largest/smallest value and stays there), to raising an exception, to doing whatever an implementation fancies. Wrap-around is, however, only one way to handle integer overflow. If you add one to the largest value, you arrive at the smallest if you subtract one from the smallest value, you get the largest. Wrap-around denotes that an integer type behaves like a circle that is, it has no beginning and no end. One possibility is what is conventionally referred to as wrap-around. Now that we know what overflow is, we can tackle the question what happens on overflow. And so shall I, for the rest of this discussion. It’s common among programmers to use the term overflow for both, overrun and underrun of a type’s value range.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |