c - 为什么在执行特定的按位运算时,uint64_t 的高 32 位会变成 1?

标签 c literals signed integer-promotion uint64

有人可以向我解释一下为什么在第 #2 种情况下,uint64_t 的高 32 位设置为 1:

uint64_t ret = 0;
ret = (((uint64_t)0x00000000000000FF) << 24);
printf("#1 [%016llX]\n", ret);

ret = (0x00000000000000FF << 24);
printf("#2 [%016llX]\n", ret);

uint32_t ret2 = 0;
ret2 = (((uint32_t)0x000000FF) << 8);
printf("#3 [%08X]\n", ret2);

ret2 = (0x000000FF << 8);
printf("#4 [%08X]\n", ret2);

输出:

#1 [00000000FF000000]
#2 [FFFFFFFFFF000000]
#3 [0000FF00]
#4 [0000FF00]

https://ideone.com/xKUaTe

您会注意到我给出了一个“等效”32 位版本(案例 #3 和 #4),但它没有表现出相同的行为...

最佳答案

默认情况下,不带后缀的整数文字的类型为 int如果它们适合 int .

The type of the integer constant

The type of the integer constant is the first type in which the value can fit, from the list of types which depends on which numeric base and which integer-suffix was used.

  • no suffix
  • decimal bases:
    • int
    • long int
    • unsigned long int (until C99)
    • long long int (since C99)
  • binary, octal, or hexadecimal bases:
    • int
    • unsigned int
    • long int
    • unsigned long int
    • long long int (since C99)
    • unsigned long long int (since C99)
  • ...

结果0x00000000000000FF将是 int不管你输入了多少个零。你可以通过打印 sizeof 0x00000000000000FF 来检查。

因此,0x00000000000000FF << 24结果为 0xFF000000,这是一个负值1。当转换到 uint64_t 时,这将再次被符号扩展。 ,将高32位补为1

转换帮助,如 (uint64_t)0x00000000000000FF) << 24 中所示,因为现在类次在 uint64_t 上运行值而不是 int 。您还可以使用后缀

0x00000000000000FFU << 24
0x00000000000000FFULL << 24

上面的第一行在 unsigned int 中进行了转换然后进行零扩展以转换为 uint64_t 。第二个执行 unsigned long long 中的操作直接

0x000000FF << 8不会暴露相同的行为,因为结果是 0xFF00,它没有设置符号位,但如果你这样做 (int16_t)0x000000FF << 8 就会出现这种情况

有很多相关和重复的问题:

<小时/>

1 从技术上讲,转换到符号位会导致未定义的行为,但在您的情况下,编译器选择保留与转换无符号值时相同的结果:0xFFU << 24 = 0xFF000000U当转换为有符号时会产生负值

查看

关于c - 为什么在执行特定的按位运算时,uint64_t 的高 32 位会变成 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33127326/

相关文章:

c - 连接到数据库的 Pro C 代码给出段错误

f# - F# 中的类型提供程序和静态参数

javascript - 将 JS 注入(inject) Literal 并在页面加载后触发

android - 如何将 Apk 签名 key 从 SHA-1 更改为 SHA256

c - 为什么程序没有正确获取输入

c - GCC 正在生成充满零的二进制文件

objective-c - 如何判断一个线程是否有锁?

java - 5 * 5 是文字还是只是一个表达式?

java - 还有其他方式使用签名小程序吗

c++ - 如何检测分配给 size_t 的负数?