q09*_*987 5 c++ undefined-behavior
#include <iostream>
using namespace std;
int main()
{
cout << "sizeof(unsigned int): " << sizeof(unsigned int) << endl;
unsigned a = 1;
int i = 0;
while (a) {
cout << "a[" << i++ << "]: " << a << endl;
a <<= 1;
}
cout << "a[" << i << "]: " << a << endl;
unsigned b = 1;
unsigned c = (b << 31);
unsigned d = (b << 32);
cout << "c: " << c << endl;
cout << "d: " << d << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
/*输出http://www.compileonline.com/compile_cpp_online.php*/
Compiling the source code....
$g++ main.cpp -o demo -lm -pthread -lgmpxx -lgmp -lreadline 2>&1
main.cpp: In function 'int main()':
main.cpp:19:23: warning: left shift count >= width of type [enabled by default]
Executing the program....
$demo
sizeof(unsigned int): 4
a[0]: 1
a[1]: 2
a[2]: 4
a[3]: 8
a[4]: 16
a[5]: 32
a[6]: 64
a[7]: 128
a[8]: 256
a[9]: 512
a[10]: 1024
a[11]: 2048
a[12]: 4096
a[13]: 8192
a[14]: 16384
a[15]: 32768
a[16]: 65536
a[17]: 131072
a[18]: 262144
a[19]: 524288
a[20]: 1048576
a[21]: 2097152
a[22]: 4194304
a[23]: 8388608
a[24]: 16777216
a[25]: 33554432
a[26]: 67108864
a[27]: 134217728
a[28]: 268435456
a[29]: 536870912
a[30]: 1073741824
a[31]: 2147483648
a[32]: 0
c: 2147483648
d: 1
Run Code Online (Sandbox Code Playgroud)
问>正如你所看到a[32等于0.现在为什么d没有0,但1?
Sti*_*sis 14
这是C/C++中未定义的行为.
标准特别保留了这个未定义的标准,因为不同的CPU在出现这种转变时会做不同的事情.具体来说,在32位Intel上,我相信CPU只使用了移位量的低5位,其余的位只是被忽略了.如果我没记错的话,PowerPC和64位Intel都使用低6位而忽略其余的位.
更高级别的语言可能会尝试通过将结果更正逻辑地保持一致来平滑这一点,但是像C/C++这样的低级语言被设计为"接近金属"并且希望生成单个位移操作<<员的指导.
b << 32是未定义的行为,因为b(unsigned int)的大小在您的机器中是32位.
C++11§5.8转换运算符
操作数应为整数或无范围的枚举类型,并执行整体促销.结果的类型是提升的左操作数的类型.如果右操作数为负数,或者大于或等于提升左操作数的位长度,则行为未定义.