我想检查一些大的计算内存需求(存储在unsigned long long
中)是否与用于编译代码的内存模型大致兼容。
我假设,当且仅当内存需求适合虚拟地址空间(独立于实际操作系统的限制)时,将指针中的需求右移位数将导致0。
不幸的是,当我在一些编译器上将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 unsignedn";
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。
在gcc中可以正常工作。
但是MSVC 13:
- 在32位调试中:unsigned上的32位rshift为NO EFFECT(显示原始数字),但unsigned long的64位位移如预期的那样为0。
- 在64位调试中:rshift在两种情况下都没有效果。
- 在32位和64位版本中:rshift在这两种情况下都是0。
我想知道这是一个编译器的错误,或者如果这是未定义的行为。
根据c++标准(5.8 Shift操作符)
- …如果右操作数为负,或大于或等于升格数的长度,则未定义左操作数
C标准(6.5.7位移位操作符)
3对每个操作数进行整数提升。的结果的类型是提升后的左操作数的类型。如果值右操作数的值为负,或者大于等于