Here's an example indicating how we can use overflow from INT_MAX to INT_MIN to terminate a loop... ...if signed overflow would be properly defined.
/* Write \"hi\" n times, counter will wrap to negative
* to indicate we've written enough greetings.
*
* i=3 -> we want to write hi three times
*
* 1st INT_MAX-i+1 = INT_MAX-2 -> write hi
* 2nd INT_MAX-1 -> write hi
* 3rd INT_MAX -> write hi
* 4th INT_MIN (signed overflow, terminates loop)
*/
int
write_n_times_hi(int i)
{
int j;
for (j=INT_MAX-i+1; j>0; j++)
printf("hi\n");
return i;
}
This will be compiled into an endless loop by gcc 5.3.0/x86_64 for -O3, but will terminate properly with -O0.
If you change the (undefined for j=INT_MAX)
j++
into the (defined)
*((unsigned*)&j)++,
the compiler may no longer assume that j stays >0 all of the time, and the loop has to terminate.
If you change the (undefined for j=INT_MAX)
into the (defined) the compiler may no longer assume that j stays >0 all of the time, and the loop has to terminate.