C++ 在C+中将64位值左移64位+;给出奇怪的结果

C++ 在C+中将64位值左移64位+;给出奇怪的结果,c++,64-bit,bit-manipulation,shift,C++,64 Bit,Bit Manipulation,Shift,可能重复: 我使用的是64位Windows 8上的Visual Studio 2012,以调试模式下的x64为目标,使用的是AMD Phenom II。 所以基本上 uint64_t Foo = 0xFFFFFFFFFFFFFFFF << 64;//Foo is now 0x0000000000000000 uint64_t Derp = 64; uint64_t Bar = 0xFFFFFFFFFFFFFFFF << Derp;//Foo is now 0xFFFFF

可能重复:

我使用的是64位Windows 8上的Visual Studio 2012,以调试模式下的x64为目标,使用的是AMD Phenom II。
所以基本上

uint64_t Foo = 0xFFFFFFFFFFFFFFFF << 64;//Foo is now 0x0000000000000000
uint64_t Derp = 64;
uint64_t Bar = 0xFFFFFFFFFFFFFFFF << Derp;//Foo is now 0xFFFFFFFFFFFFFFFF

<代码> Unt64→Fo0= 0xFffffffffffffffff> p>我相信在C++中没有整数或更大的移位。

您的第一个示例在编译时进行评估,因为它只涉及常量。第二个示例由处理器在运行时计算

您可以将班次分为两部分:

uint64_t Bar = 0xFFFFFFFFFFFFFFFF << (Derp / 2);
Bar <<= Derp - (Derp / 2);

uint64\u t Bar=0xFFFFFFFFFFFFFFFF如果移位值大于或等于位宽度,则移位操作具有未定义的行为

根据C++11草案第5.8节p1:

操作数应为整数或无范围枚举类型,并执行整数升级。 结果的类型是提升的左操作数的类型。如果正确的操作数 为负,或大于或等于提升后的左操作数的位长度


他们为什么这样做?这在Java中是一样的,没有意义,如果>,它应该设置为零,如果>>@gia标准体通常决定使行为未定义,这样编译器实现者就不必生成昂贵(缓慢)的代码来处理边缘情况。它可能出现在芯片上或其他东西上,我的意思是,不管怎样,我最终还是要做检查:P@gia如果参数是一个文本常量,则不需要进行任何检查。如果参数不是文本,我只是添加了检查,代码不可读