从 double 转换总是返回零

Eci*_*ana 3 c c++ gcc clang

为什么以下代码在使用 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

  • 可能想要添加源:https://timsong-cpp.github.io/cppwp/conv.fpint#1 (2认同)