I found this example, can anyone explain what's going on here? I'm using LLVM 7.1.
uint8_t a = 0xff;
a = ~a >> 1;
// a = 0b1000000
uint8_t b = 0xff;
b = ~b;
b = b >> 1;
//b = 0
a
and b
should be equal??
EDIT: Added the disassembly:
testt`main:
0x100000f70 <+0>: pushq %rbp
0x100000f71 <+1>: movq %rsp, %rbp
0x100000f74 <+4>: xorl %eax, %eax
0x100000f76 <+6>: movl $0x0, -0x4(%rbp)
0x100000f7d <+13>: movl %edi, -0x8(%rbp)
0x100000f80 <+16>: movq %rsi, -0x10(%rbp)
0x100000f84 <+20>: movb $-0x1, -0x11(%rbp)
0x100000f88 <+24>: movzbl -0x11(%rbp), %edi
0x100000f8c <+28>: xorl $-0x1, %edi
0x100000f8f <+31>: sarl $0x1, %edi
0x100000f92 <+34>: movb %dil, %cl
0x100000f95 <+37>: movb %cl, -0x11(%rbp)
0x100000f98 <+40>: movb $-0x1, -0x12(%rbp)
0x100000f9c <+44>: movzbl -0x12(%rbp), %edi
0x100000fa0 <+48>: xorl $-0x1, %edi
0x100000fa3 <+51>: movb %dil, %cl
0x100000fa6 <+54>: movb %cl, -0x12(%rbp)
0x100000fa9 <+57>: movzbl -0x12(%rbp), %edi
0x100000fad <+61>: sarl $0x1, %edi
0x100000fb0 <+64>: movb %dil, %cl
0x100000fb3 <+67>: movb %cl, -0x12(%rbp)
0x100000fb6 <+70>: popq %rbp
0x100000fb7 <+71>: retq
In the first case ~a
is promoted to int
, so you get:
a = 0xffffff00 >> 1 = 0x7fffff80
which is truncated to 0x80
.
In the second case, the truncation happens before the shift, so you get:
b = 0xffffff00
which is truncated to 0x00
, and then shifting this gives a result of 0x00
.
(Note: the above assumes 32 bit ints, normal 2s complement representation and logical right shifting of signed values.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With