Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 296
chux - Reinstate Monica Avatar asked Nov 10 '16 21:11

chux - Reinstate Monica


1 Answers

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.

like image 133
P.P Avatar answered Sep 27 '22 21:09

P.P