4

Consider this program

#include <limits.h>

int main (void) {
    int i = 0;

    // Assume, user is a fair person, following the instruction strictly..
    printf ("Enter a number in the range [0 - INT_MAX] : \n"); 
    scanf ("%d", &i);

    while (i++ < INT_MAX) {
        // do some stuff..
        // value of variable i not used in loop body
    }

    // value of variable i is not used anywhere after loop body

    return 0;
}

In the last evaluation of loop condition i++ < INT_MAX, the value of i in the expression will be INT_MAX, but i will be holding the result of INT_MAX + 1 (side effect of post increment), which is essentially signed integer overflow. The loop condition (INT_MAX < INT_MAX) result in false and loop exits. The value of variable i not used anywhere in the program after the loop body but, of course, once the loop exits it is holding the result of INT_MAX + 1.

Does this program possess undefined behavior?

PS:

  • I have searched around it and found a couple of related question but they are not exactly same:

does-integer-overflow-cause-undefined-behavior-because-of-memory-corruption

is-it-undefined-behavior-if-the-intermediate-result-of-an-expression-overflows

In both the above question, the value of variable/expression resulting in overflow is used in some way or other.

  • My question is very specific and pointed to undefined behavior, I am not looking for any other way of doing stuff shown in sample program. I know very well, how to avoid UB.

  • I would appreciate if you include citation (if any), supporting the behavior (whether UB or not), from language standard in your post.

H.S.
  • 11,654
  • 2
  • 15
  • 32
  • Does this answer your question? [C integer overflow](https://stackoverflow.com/questions/12335784/c-integer-overflow) – President James K. Polk Aug 31 '23 at 01:47
  • @PresidentJamesK.Polk I am aware it. My question is specific to the loop condition. Note that variable `i` is not used anywhere in loop body and after loop. – H.S. Aug 31 '23 at 01:50
  • 2
    MIPS signed addition generates an exception on overflow https://stackoverflow.com/q/9559145/1216776 – stark Aug 31 '23 at 02:10
  • @stark Arguably that's not the desired behavior on any ISA. Any sane ISA will merely raise a flag when finding signed overflow and still produce a deterministic result - a 2's complement wrap-around. Although signed overflow is probably a bug, very few programmers want the outcome of that bug to be "crash and burn". Informing the programmer about a bug vs purposely crashing the end application are two different things. – Lundin Aug 31 '23 at 09:22

3 Answers3

3

Does this program possess undefined behavior?

Yes, that is very clear.

You don't have to access the value of i after it overflows for the overflow to have happened, and once the overflow has happened, you have invoked undefined behavior.

If somebody compiles your program with GCC and uses the -ftrapv flag, your program will crash as soon as the overflow occurs, regardless of whether you would later have attempted to access i.

user229044
  • 232,980
  • 40
  • 330
  • 338
3

I would appreciate if you include citation (if any), supporting the behavior (whether UB or not), from language standard in your post.

C 2018 6.5.2.4 discusses postfix ++. Paragraph 2 says:

… As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it). See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers…

6.5.6 discusses the additive operators. Paragraph 5 says:

The result of the binary + operator is the sum of the operands.

6.5 paragraph 5 says:

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.

Therefore, when i++ is evaluated with i equal to INT_MAX, it effectively evaluates INT_MAX + 1, and an exceptional condition occurs, so the behavior of the program is not defined by the C standard.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
2

You seem to be under the mistaken impression that undefined behavior means that your program will behave in a manner you might not expect. That is not what it means.

When a program contains undefined behavior, the C standard makes no guarantees regarding what that program will do. It might crash, it might give unexpected results, or it might appear to work properly.

As you seem to have gathered from your initial research, signed integer overflow is indeed undefined behavior. Whether or not you subsequently attempt to use i doesn't matter. Your program still has undefined behavior.

Whether you're likely to see any unusual behavior in this particular instance, probably not, but again there's no guarantee of that.

dbush
  • 205,898
  • 23
  • 218
  • 273