将UINT32_T铸造为UINT64_T会导致不同的值
casting uint32_t to uint64_t results in different value?
使用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都给我我期望的数字。
编辑:我已经使用具有相同问题的更简单版本更新代码。另外,我刚刚提交了一个错误报告。
我可以在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/
相关文章:
- 关于uint64的atomic_fetch_add的奇怪行为
- memcpy 是将浮子打包到 uint32 中的标准方法吗?
- 警告C4018,包含int和UINT32,但不包含int和UCHAR
- 为什么 UInt64 变量不能包含大于 UInt32::Max 的值?
- C++:从 "const variable*" 转换为"uint32"会失去精度
- 从指针到 uint32 的类型转换
- 为什么当我使用双精度时,Qt<->Matlab 正确写入和读取我的字节,但存储 uint32 的字节不正确?
- uint32, int16, uint8 .为什么这些常用的数据类型没有进入标准
- 将字符 * 转换为 uint16 和 uint32
- 如何将UINT8*施放到UINT32
- 从 2 个 uint64 值中提取诡异哈希 128 位值
- 将模板类型名称转换为 uint64
- 在 VS 移位中,UINT64 上的左移(64 >移位> 32)位仅 32 位
- 从4个浮子创建UINT32
- 如果FF的参数为UINT64类型,则无法返回正确的结果
- 访问联合的成员变量:为 uint64 声明,但想要在 uint32 中的内容。C++
- UInt64在32位系统上,需要从UInt32's字节数组生成,如何
- 用于在稀疏机器学习中生成uint64或uint32特征id的良好哈希函数
- 当数字声明为uint32和uint64时,将整数转换为二进制会显示不同的输出
- 将float转换为uint64和uint32的行为很奇怪