将UINT32_T铸造为UINT64_T会导致不同的值

casting uint32_t to uint64_t results in different value?

本文关键字:UINT64 UINT32      更新时间:2023-10-16

使用Visual Studio 2015 C ,14.0.25431.01更新3.我的代码中有意外的行为。编译并运行64位,发行:

#include <iostream>
#include <stdint.h>
int main(int, char**) {
    for (uint32_t i = 1; i < 3; ++i) {
        uint32_t a = i * 0xfbd1e995;
        uint64_t b = a;
        std::cout << a << " 32bit" << std::endl;
        std::cout << b << " 64bit" << std::endl;
    }
}

我希望 ab具有相同的值,但是当我运行时,我会得到此输出:

4224838037 32bit
4224838037 64bit
4154708778 32bit
8449676074 64bit

看起来编译器用64位乘法代替了32位乘法。是否允许这样做,还是这是编译器错误?G 和Clang都给我我期望的数字。

编辑:我已经使用具有相同问题的更简单版本更新代码。另外,我刚刚提交了一个错误报告。

我可以在VS2010上复制此,而直接的原因是:

add ebx, 5BD1E995h  ; this is x
add rdi, 5BD1E995h  ; this is a 64bit version of x

由于它是一个64位的添加,它将仅带入高32位。这至少比召集64位乘法更有意义,这可能是诱导变量消除的角度案例,但这只是猜测。

还有趣的是,它甚至不会通过放入铸件来保存演员。正确的值就在rbx中。

看来,这个hotfix解决了问题,至少对于VS 2015:

https://support.microsoft.com/en-us/help/3207317/visual-c-poptimizer-fixes-for-visual-visual-studio-2015-update-3

,但似乎VS 2008,2010,2013仍然受此错误的影响。

来源:

  • https://www.reddit.com/r/cpp/comments/5wwwmi2/visual_studio_2015_compiler_compiler_bug_64bit_instead_of/deddfw27/
  • https://www.reddit.com/r/cpp/comments/5wwwmi2/visual_studio_2015_compiler_compiler_bug_64bit_instead_of/dedzh5g/