chux
chux

Reputation: 154280

When an `int` at max value and tested with with postfix ++, is code well-defined?

EXAMPLE An example of undefined behavior is the behavior on integer overflow. C11dr §3.4.3 3

int overflow is undefined behavior, but does that apply to the following which exists the loop, and does not use the the side effect of the now out-of-scope i? In particular, does this Postfix increment spec help?

... The value computation of the result is sequenced before the side effect of updating the stored value of the operand. ... §6.5.2.4 2

Compiles without warnings with well-enabled C11

#include <limits.h>
#include <stdio.h>

int main(void) {
  // Specified behavior when `i` has the value `INT_MAX`?
  for (int i = INT_MAX - 2; i++ < INT_MAX;) {
    printf("%d\n", i);
  }
  puts("Done");
  return 0;
}

Sample output

2147483646
2147483647
Done

Of course code can be re-written to avoid this quandary with the below. Still, looking for confirmation concerning the above. (I think it is UB.) A similar issue exists with INT_MIN and i--.

  for (int i = INT_MAX - 2; i < INT_MAX;) {
    i++; 
    printf("%d\n", i);
  }

GNU C11 (GCC) version 5.3.0 (i686-pc-cygwin)
    compiled by GNU C version 5.3.0, GMP version 6.1.0, MPFR version 3.1.4, MPC version 1.0.3
'-std=c11' '-O0' '-g3' '-Wpedantic' '-Wall' '-Wextra' '-Wconversion' '-c' '-fmessage-length=0' '-v' '-MMD' '-MP' '-MF' xx.o' '-o' 'xx.o' '-mtune=generic' '-march=i686'
/usr/lib/gcc/i686-pc-cygwin/5.3.0/cc1.exe -quiet -v -MMD xx.d -MF xx.d -MP -MT xx.o -dD -Dunix -idirafter   ... xx.c

Upvotes: 7

Views: 95

Answers (2)

P.P
P.P

Reputation: 121407

Regardless of the scope i, the program has undefined behaviour in the evaluaton of i++ when i is 2147483647 (assuming INT_MAX=2147483647 on your system).

Your example can be re-written as:

include <limits.h>

int main(void) {
  // Specified behavior when `i` has the value `INT_MAX`?
  {
      int i = INT_MAX;
      i++;
  }
  puts("Done");
  return 0;
}

The value computation of i++ results in integer overflow irrespective of whether the computed value is used or if that object cease to exist right after the next sequence point; sequence point or storage duration of the object is irrelevant whether there's an undefined behaviour here.

Upvotes: 4

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215387

The code has undefined behavior. The expression i++ causes evaluation of i+1 and assignment of the result to i, and the evaluation of i+1 has undefined behavior. It doesn't matter that you don't use the result of i+1 or the newly stored value of i. UB is not a matter of using the result. Likewise, 0*(INT_MAX+1) has UB.

Upvotes: 4

Related Questions