示例未定义行为的示例是整数溢出的行为.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)
无论范围如何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++无论是否使用计算值,或者该对象在下一个序列点之后不再存在, 的值计算都会导致整数溢出;对象的序列点或存储持续时间与这里是否存在未定义的行为无关。