是否将一个无符号整数右移了它的总位数 UB ?

Is right-shifting an unsigned integer by its total number of bits UB ?

我想检查一些大的计算内存需求(存储在 unsigned long long 中)是否与用于编译我的代码的内存模型大致兼容。

我假设将需求右移指针中的位数将导致 0 当且仅当内存需求适合虚拟地址 space(独立于实际 OS 限制)。

不幸的是,在某些编译器上将 64 位数字移位 64 位时,我发现了一些意想不到的结果。

小演示:

const int ubits =  sizeof (unsigned)*8;  // number of bits, assuming 8 per byte
const int ullbits =  sizeof (unsigned long long)*8; 
cout << ubits << " bits for an unsigned\n"; 
cout << ullbits << " bits for a unsigned long long \n";

unsigned  utest=numeric_limits<unsigned>::max();  // some big numbers
unsigned long long ulltest=numeric_limits<unsigned long long>::max();

cout << "unsigned "<<utest << " rshift by " << ubits << " = "
    << (utest>>ubits)<<endl; 
cout << "unsigned long long "<<ulltest << " rshift by " << ullbits << " = "
    << (ulltest>>ullbits)<<endl; 

我预计两个显示的 rshit 结果都是 0。

这个works as expected with gcc

但是对于 MSVC 13:

我想知道这是编译器错误,还是未定义的行为。

根据 C++ 标准(5.8 移位运算符)

  1. ...The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand

C标准(6.5.7位移位运算符)中也是这样写的

3 The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined.