c - 为什么这两种将变量设置为全 1 的方法会导致不同的结果?

标签 c

我最近发现在 C 中将变量设置为全 1 的两种方法之间存在差异。 这是一个小代码示例,用于说明我的 64 位 Linux 系统上的奇怪行为。

// compile with `gcc -o weird_shift_behaviour weird_shift_behaviour.c`

#include <stdio.h>

int main(void){
    long long foo = 0;
    long long bar = 0;
    int i;
    puts("<foo> will be set to all 1s by repeatedly shifting 1 to the left and OR-ing the result with <foo>.");
    puts("<bar> will be set to all 1s by repeatedly OR-ing it with 1 and shifting <bar> to the left one step.");
    for(i=0;i<8*(int)sizeof(long long)-1;++i){
        foo |= (1<<i);
        bar = bar<<1 | 1;
        printf("<i>: %02d <foo>: %016llx <bar>: %016llx \n",i,foo,bar);
    }
    return 0;
}

我确实知道这不是在 C 中将整数类型设置为全 1 的规范方法,但我还是尝试过。以下是示例程序生成的输出中有趣的部分:

<i>: 29 <foo>: 000000003fffffff <bar>: 000000003fffffff 
<i>: 30 <foo>: 000000007fffffff <bar>: 000000007fffffff 
<i>: 31 <foo>: ffffffffffffffff <bar>: 00000000ffffffff 
<i>: 32 <foo>: ffffffffffffffff <bar>: 00000001ffffffff 

为什么会出现这种奇怪的行为?到目前为止,我想不出任何合理的解释。

最佳答案

1<<i

1类型为 int1 << 31int 时是未定义的行为是 32 位宽。

来自 C 标准:

(C99, 6.5.7p4) "The result of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. [...] If E1 has a signed type and nonnegative value, and E1 x 2 ^ E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined."

要解决您的问题,请更改 1<<i1ULL << i .

关于c - 为什么这两种将变量设置为全 1 的方法会导致不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21525495/

相关文章:

c - 是否可以向 GDB 添加对自定义 RTOS 线程的支持?

c - fwrite 是原子的吗?

c - 使用 GetProcessMemoryInfo 查找内存利用率

objective-c - 为简单的命令行程序编译Apple框架

c++ - 默认堆栈大小

c - C ncurses 应用程序中的希伯来语支持

C 指针错误

扩展后连接#define

c - fstat : st_atime and st_mtime not a member?

c - 错误: invalid use of vector register at operand 1