为什么 IS_ERR_VALUE 将负 MAX_ERRNO 转换为 unsigned long?

ves*_*len 3 c error-code linux-kernel

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

#define MAX_ERRNO       4095

#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
Run Code Online (Sandbox Code Playgroud)

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

ves*_*len 5

它看起来像是一种优化,仅使用一次比较来检查是否x-4095和 之间-1,也称为有效的错误代码。对于 asigned long你需要两个比较:

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

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

因此,条件将返回 true if ,这对于tox >= 0xff...ff001的有符号范围(有效错误代码范围)为 true。-4095-1