我想检查一些大的计算内存需求(存储在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 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.
但是对于MSVC 13:
我想知道这是否是编译器错误,或者这是否是未定义的行为。
答案 0 :(得分:5)
根据C ++标准(5.8移位运算符)
- ... 行为未定义如果右操作数为负数,或者大于或等于提升位的长度 左操作数
醇>
C标准(6.5.7按位移位运算符)
中写的相同3对每个操作数执行整数提升。该 结果的类型是提升的左操作数的类型。如果值 右操作数为负数或大于或等于 提升左操作数的宽度,行为未定义。