为什么IS_ERR_VALUE将负MAX_ERRNO转换为无符号长整数?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么IS_ERR_VALUE将负MAX_ERRNO转换为无符号长整数?相关的知识,希望对你有一定的参考价值。

include/linux/err.h中,有以下定义:

#define MAX_ERRNO       4095

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)

我的想法是检查在指针位置返回的有效错误号,但为什么MAX_ERRNO在被转换为无符号之前在它前面有一元-?看起来这会导致x与最大长度减去MAX_ERRNO而不是4095进行比较。

答案

它看起来像一个优化,只使用一个比较来检查x是否在-4095-1之间,也就是有效的错误代码。对于signed long,你需要两个比较:

(x >= -4095 && x < 0)

将-4095投射到unsigned long会产生0xff...ff001,它在到达ULONG_MAX之前只有4094个整数。这些值也是地址空间末尾的无效指针地址(因此,此范围用于返回void指针的函数中的错误代码)。

因此,如果x >= 0xff...ff001,则条件将返回true,对于-4095-1的有符号范围(有效的错误代码范围),该条件为真。

以上是关于为什么IS_ERR_VALUE将负MAX_ERRNO转换为无符号长整数?的主要内容,如果未能解决你的问题,请参考以下文章

将负十进制转换为其二进制表示

将负分数转换为 IEEE 754

如何将负二进制数转换为int?

使用 if_abs 将负整数转换为正数 [重复]

将负二进制数转换为十进制数

将负双精度转换为无符号整数的行为是不是在 C 标准中定义? ARM 与 x86 上的不同行为