14

使用 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;
    }
}

我期望它a具有b相同的值,但是当我运行它时,我得到了这个输出:

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

看起来编译器用 64 位乘法替换了 32 位乘法。是否允许这样做,或者这是一个编译器错误?g++ 和 clang 都给了我期望的数字。

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

4

2 回答 2

7

我可以在 VS2010 上重现这个,直接原因是这样的:

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

由于它是 64 位加法,它只会进位到高 32 位。这至少比变出一个 64 位乘法更有意义,它可能是归纳变量消除的一个极端情况,但这只是猜测。

同样有趣的是,它甚至不会通过错误编译来保存演员表。正确的值就在rbx.

于 2017-02-28T14:53:40.707 回答