2016-04-27 7 views
8

Znalazłem ten przykład, czy ktoś może wyjaśnić, co tu się dzieje? Używam LLVM 7.1.C zachowanie bitshifting

uint8_t a = 0xff; 
a = ~a >> 1; 
// a = 0b1000000 

uint8_t b = 0xff; 
b = ~b; 
b = b >> 1; 
//b = 0 

a i b powinna być równa ??

EDIT: Dodany demontaż:

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 
+1

Nie, nie _should_ oni. Implementacja określonego zachowania. Za mało informacji. Spójrz na wyjście asemblera. – Olaf

+0

"a i b powinny być równe" dlaczego? Kod jest inny. –

+0

@Olaf: Dlaczego jest to defiend implementacji? Prawe przesunięcie liczby całkowitej bez znaku jest na pewno pewne? Jeśli został podpisany, byłoby UB ... – Jimbo

Odpowiedz

10

W pierwszym przypadku ~a jest promowany do int, więc masz:

a = 0xffffff00 >> 1 = 0x7fffff80 

który jest obcinany do 0x80.

W drugim przypadku obcięcia dzieje przed przesunięcie, więc masz:

b = 0xffffff00 

który jest obcinany do 0x00, a następnie przesunięcie daje to wynik 0x00.

(Uwaga: powyższa zakłada 32-bitowych ints normalne 2s uzupełnienie reprezentacji i logicznego prawo przesunięcia podpisanych wartości.)

+1

Tylko dla 32 bit 'int' (możliwy) i tylko dla uzupełnienia 2 (prawdopodobnie). Nie promuje się również '~ a', ale' a'. '~' jest już wykonane na 'int'. – Olaf

+0

Dzięki @Olaf - dodam notatkę do tego efektu. –

+2

Wow, bardzo imponujące, dzięki :) – iCaramba