32 = 0x%X\n", (~0x0U) >> 32); p-6ren">
gpt4 book ai didi

c - 使用 gcc 进行位移位的意外行为

转载 作者:IT王子 更新时间:2023-10-29 01:03:19 32 4
gpt4 key购买 nike

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

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;
}

它产生以下输出:

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

我期望 (1) 和 (3) 相同,以及 (2) 和 (4) 相同。

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

发生了什么事?

最佳答案

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

你的编译器应该警告你:

$ 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]

如果您查看 assembler code gcc 正在生成,您会看到它实际上是在编译时计算前两个结果。简化:

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

关于c - 使用 gcc 进行位移位的意外行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7214263/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com