Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a test program like this:

int main()
{
    unsigned n = 32;

    printf("ans << 32 = 0x%X
", (~0x0U) << 32);
    printf("ans >> 32 = 0x%X
", (~0x0U) >> 32);

    printf("ans << n(32) = 0x%X
", (~0x0U) << n);
    printf("ans >> n(32) = 0x%X
", (~0x0U) >> n);

    return 0;
}  

It produces the following output:

ans << 32 = 0x0  ... (1)  
ans >> 32 = 0x0  ... (2)  
ans << n(32) = 0xFFFFFFFF  ... (3)  
ans >> n(32) = 0xFFFFFFFF  ... (4)   

I was expecting (1) and (3) to be the same, as well as (2) and (4) to be the same.

Using gcc version: gcc.real (Ubuntu 4.4.1-4ubuntu9) 4.4.1

What is happening?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.2k views
Welcome To Ask or Share your Answers For Others

1 Answer

Shifting by the size of the type is undefined behavior, according to the C standard, § 6.5.7.3:

6.5.7 Bitwise shift operators
(...) If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is unde?ned.

Your compiler should warn you about this:

$ gcc shift.c -o shift -Wall
shift.c: In function ‘main’:
shift.c:5:5: warning: left shift count >= width of type [enabled by default]
shift.c:6:5: warning: right shift count >= width of type [enabled by default]

If you look at the assembler code gcc is generating, you'll see it is actually calculating the first two results at compilation time. Simplified:

main:
    movl    $0, %esi
    call    printf

    movl    $0, %esi
    call    printf

    movl    -4(%rbp), %ecx  ; -4(%rbp) is n
    movl    $-1, %esi
    sall    %cl, %esi       ; This ignores all but the 5 lowest bits of %cl/%ecx
    call    printf

    movl    -4(%rbp), %ecx
    movl    $-1, %esi
    shrl    %cl, %esi
    call    printf

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...