当一个`int`处于最大值并使用postfix ++进行测试时,代码是否定义良好?

chu*_*ica 7 c language-lawyer

示例未定义行为的示例是整数溢出的行为.C11dr§3.4.33

intoverflow是未定义的行为,但这是否适用于存在循环的以下内容,并且不使用现在超出范围的副作用i?特别是,这个Postfix增量规范有帮助吗?

...在更新操作数的存储值的副作用之前,对结果的值计算进行排序.......§6.5.2.42

使用启用良好的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;
}
Run Code Online (Sandbox Code Playgroud)

样本输出

2147483646
2147483647
Done
Run Code Online (Sandbox Code Playgroud)

当然可以重写代码以避免下面的这种窘境.仍然,寻找有关上述的确认.(我认为这是UB.)与INT_MIN和存在类似的问题i--.

  for (int i = INT_MAX - 2; i < INT_MAX;) {
    i++; 
    printf("%d\n", i);
  }
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

P.P*_*.P. 4

无论范围如何i,程序在计算i++wheni为2147483647 时都有未定义的行为(假设您的系统上的INT_MAX=2147483647)。

您的示例可以重写为:

include <limits.h>

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

i++无论是否使用计算值,或者该对象在下一个序列点之后不再存在, 的值计算都会导致整数溢出;对象的序列点或存储持续时间与这里是否存在未定义的行为无关。