3

Where in the C99 standard does it say that signed integer overflow is undefined behavior?

I see the comment about unsigned integer overflow being well-defined (see Why is unsigned integer overflow defined behavior but signed integer overflow isn't?) in section 6.2.5:

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.

but I'm looking in Appendix J on undefined behaviors, and I only see these similar items in the list:

An expression having signed promoted type is left-shifted and either the value of the expression is negative or the result of shifting would be not be representable in the promoted type

and

The value of the result of an integer arithmetic or conversion function cannot be represented

(note this refers to "an integer arithmetic function", not integer arithmetic itself

Community
  • 1
  • 1
Jason S
  • 184,598
  • 164
  • 608
  • 970
  • 2
    C99 draft standard n1256 *6.5 Expressions 5 If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.* – EOF Mar 31 '16 at 19:52
  • @EOF: Why not post that as an answer? – Nate Eldredge Mar 31 '16 at 20:03
  • @NateEldredge: There is an answer citing the C11 draft standard, which is identical in this regard, as far as I can see. – EOF Mar 31 '16 at 20:04
  • Appendix J is non-normative, it's just meant to be a summary – M.M Mar 31 '16 at 20:07
  • aha this SO question is similar: http://stackoverflow.com/questions/3679047/integer-overflow-in-c-standards-and-compilers – Jason S Mar 31 '16 at 20:28

1 Answers1

5

I don't have a copy of C99, but in the C11 standard this text appears in Section 6.5, paragraph 5:

If an exceptional condition occurs during the evaluation of an expression (that is, if the result is not mathematically defined or not in the range of representable values for its type), the behavior is undefined.

Which would seem to be a catch-all for any overflow; the text about unsigned integers then becomes a special-case above 6.5 ¶ 5.

Haldean Brown
  • 12,411
  • 5
  • 43
  • 58
  • ah -- I missed this somehow. Thanks! It seems like the comment on unsigned overflow should be stated more strongly; it sounds like it's implied by other parts of the standard ("Oh, this is true because of this") but I don't see the modulo behavior cited elsewhere in the standard. – Jason S Mar 31 '16 at 20:27
  • Yeah; it's kind of odd that it isn't present in Appendix J as an exception to the "value of a result" rule. Glad I could help! – Haldean Brown Mar 31 '16 at 20:28
  • @JasonS: You could have a look at C11 draft standard n1570, *6.2.6.2 Integer types 1 For unsigned integer types other than unsigned char, the bits of the object representation shall be divided into two groups: value bits and padding bits (there need not be any of the latter). If there are N value bits, each bit shall represent a different power of 2 between 1 and 2 N −1 , so that objects of that type shall be capable of representing values from 0 to 2 N − 1 using a pure binary representation; this shall be known as the value representation. The values of any padding bits are unspecified.* – EOF Mar 31 '16 at 20:38
  • omg that is so speccy, I can read that and it both makes perfect sense and I have no idea why it matters. – Jason S Apr 01 '16 at 04:38
  • It may be worth noting that many implementations predefine macros which promise that floating-point math will behave according to an annex which defines behavior in many out-of-bounds conditions. Further, it used to be that specification of two's-complement for integer storage and computation was considered a full behavioral definition for all integer operator and operand combinations except oversized shifts or division by zero in the absence of any documented exceptions. Many compilers would, with certain optimizations enabled, perform certain linear transforms within loops, such as... – supercat Apr 02 '16 at 17:41
  • ...computations which involve things outside the range of `int` may appear to arbitrarily clip values to the range of `int` or use arithmetically-correct values outside the range, but the existence of such behaviors would be a documented consequence of the optimizations, and wouldn't affect things like `uint1 = ushort1*ushort2;` in cases where the result was between INT_MAX and UINT_MAX. Somehow, however, it has become fashionable to use UB as an excuse to turn code whose behavior would be useful even in the presence of such optimizations, into code which will behave oddly with overflows. – supercat Apr 02 '16 at 18:43