按位的意外行为使用gcc移 [英] unexpected behavior of bitwise shifting using gcc

查看:145
本文介绍了按位的意外行为使用gcc移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试的程序是这样的:

I have a test program like this:

int main()
{
    unsigned n = 32;

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

    printf("ans << n(32) = 0x%X\n", (~0x0U) << n);
    printf("ans >> n(32) = 0x%X\n", (~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)   

我期待(1)和(3)是相同的,以及(2)和(4)是相同的。

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

使用gcc版本:gcc.real(Ubuntu的4.4.1-4ubuntu9)4.4.1

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

这是怎么回事?

推荐答案

由类型的大小为转移不确定的行为,根据的 C标准,第6.5.7.3:

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

6.5.7按位移位运算符

  (...)如果值
  右操作数为负或大于或等于更大的宽度
  推广左操作数,行为是理解过程网络定义。

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 undefined.

您编译器应该提醒你一下:

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]

如果你看一下汇编code 的gcc产生,你会看到它实际上是计算前两个结果在编译的时候。简化的:

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

这篇关于按位的意外行为使用gcc移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆