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.

3

There are 3 best solutions below

1
user229044 On BEST ANSWER

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.

0
dbush On

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.

0
Eric Postpischil On

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.