为什么以下代码在使用 clang 编译时返回零?
#include <stdint.h>
uint64_t square() {
return ((uint32_t)((double)4294967296.0)) - 10;
}
Run Code Online (Sandbox Code Playgroud)
它生产的组件是:
push rbp
mov rbp, rsp
xor eax, eax
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
我原以为 double 会变成零(整数),而那个减号会将它包裹起来。换句话说,为什么要减去的数字无关紧要,因为它总是产生零?请注意,gcc 确实产生了不同的数字,正如预期的那样:
push rbp
mov rbp, rsp
mov eax, 4294967285
pop rbp
ret
Run Code Online (Sandbox Code Playgroud)
我假设将 4294967296.0 转换uint32_t为未定义的行为,但即便如此,我仍希望为不同的减数产生不同的结果。
Bat*_*eba 15
铸造超出范围的行为double,以一个unsigned类型确实是不确定的。
环绕不适用,即使是一种unsigned类型。
这是一个经常被遗忘的规则。
一旦程序控制到达一个未定义的结构,整个程序就是未定义的,甚至有些矛盾的是,已经运行过的语句。
参考:https : //timsong-cpp.github.io/cppwp/conv.fpint#1