Why doesn't Left-Shifting an unsigned 32 times produce ZERO?

#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; } 

/ * Exit 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 

Questions> As you can see, a[32 is 0. Now why d NOT 0 , but 1 ?

+4
source share
3 answers

This behavior is undefined in C / C ++.

The standard specifically leaves this undefined, because different processors will do different things when such shifts are presented. In particular, on 32-bit Intel, I believe that only 5-bit shift values ​​are used by the processor, and the remaining bits are simply ignored. If I remember correctly, PowerPC and 64-bit Intel use low 6 bits and ignore the rest.

A higher-level language may try to smooth this out by correcting the results to be more logically consistent, but a low-level language such as C / C ++ should be “close to metal” and will generate a single bit-shift for the << operator.

+13
source

b << 32 is undefined behavior because the size of b ( unsigned int ) is 32-bit on your computer.

C ++ 11 §5.8 Shift operators

The operands must be integer or non-enumerated types of enumerations, and integral promotions are performed. The result type is the advanced left operand. The behavior is undefined if the right operand is negative or greater than or equal to the bit length of the advanced left operand.

+5
source

This is a language restriction.

To map the matching << and >> directly to machine language instructions, the language inherits hardware constraints in which shear values ​​that are negative or larger than the register often do not do what you expect.

For example, it would be nice to have

 15 << -1 

mean the same as

 15 >> 1 

but unfortunately this is not so.

+1
source

Source: https://habr.com/ru/post/1502086/


All Articles