使用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都给了我期望的数字。
编辑:我用更简单的版本更新了我的代码,这个版本有同样的问题。另外,I've just submitted a bug report。
答案 0 :(得分:7)
我可以在VS2010上重现这一点,其直接原因是:
add ebx, 5BD1E995h ; this is x
add rdi, 5BD1E995h ; this is a 64bit version of x
由于它是64位的加法,它只会进入高32位。至少比编造一个64位乘法更有意义,它可能是诱导变量消除的一个极端情况,但这只是推测。
同样有趣的是,它甚至不会通过错误编译来保存演员表。正确的值就在rbx
。
答案 1 :(得分:1)
看来这个修补程序修复了这个问题,至少在VS 2015中是这样的:
但似乎VS 2008,2010,2013仍然受到这个错误的影响。
来源: