让我们看一下代码:
#include <stdio.h>
int main()
{
unsigned char xi;
unsigned char xf;
int bi = -300;
float bf = -300;
xi = bi;
xf = bf;
printf("xi = %d\n", xi);
printf("xf = %d\n", xf);
return 0;
}
我们得到输出:
xi = 212
xf = 0
尽管预计它会unsigned char正确溢出并且两个变量都等于212. 有趣的是,当标志存在时-O0(没有优化),输出如预期:
xi = 212
xf = 212
带有标志-O1及以上,已经出现差异。
显然,我在这里踩到了某种未定义的行为,告诉我这里到底发生了什么?关节在哪里?
PS。当溢出“向上”时,如果float跳过,输出为 255,如示例中所示。
这是未定义的行为。目标类型必须包含源值。
厘米。
[conv.fpint]整数转换为无符号类型期间的溢出遵循Integral Conversions 的规则,即 照常处理,根据模运算规则。
浮点转换为无符号类型期间的溢出遵循浮点整数转换的规则- 即 这是未定义的行为。
这就是全部的区别。事实上,未定义行为的表现会根据编译器设置而改变,这并没有什么“奇怪”的。