c - 在 NULL 表示为 0 的平台上,编译器是否曾为 NULL <= p 生成意外代码

标签 c c99 undefined-behavior

在 C99 中,相等性 == 似乎从未被定义过。如果您将它应用于无效地址,它可能会意外生成 1(例如 &x + 1 == &y 可能意外为真)。它不会产生未定义的行为。许多(但不是全部)无效地址未定义为根据标准计算/使用,因此在 p == &x 中使用 p 悬空指针,或者在 &x + 2 == &y,无效地址导致未定义的行为,而不是==

另一方面,>= 和其他比较在应用于不指向同一对象的指针时是未定义的。这包括测试 q >= NULL,其中 q 是一个有效的指针。这个测试是我的问题的主题。

我从事低级嵌入式代码的静态分析器工作。这种代码做标准允许之外的事情是很正常的。例如,在这种代码中,指针数组可以用 memset(...,0,...) 初始化,尽管标准没有指定 NULL 0 必须具有相同的表示形式。为了有用,分析器必须接受这种东西,并按照程序员期望的方式解释它们。警告程序员会被视为误报。

因此分析器已经假定 NULL0 具有相同的表示(您应该根据分析器检查您的编译器以确保它们同意这种类型的假设)。我注意到一些程序将有效指针与 NULL 与 >= 进行比较(this library 是一个例子)。只要 NULL 表示为 0 并且指针比较被编译为无符号整数比较,这就会按预期工作。 我只希望分析器警告这一点,也许是因为一些积极的优化,它可能被编译成不同于程序员在传统平台上的意思的东西。因此我的问题是:在 NULL 表示为 0?

注意:这个问题不是关于在指针上下文中使用 0 来获取空指针。关于 NULL 表示的假设是一个真实的假设,因为在 memset() 示例中没有转换。

最佳答案

肯定有一些指针,当您将它们重新解释为指针大小的带符号整数时,它们将具有负号。

特别是 Win32 上的所有内核内存,如果您使用“大地址感知”,那么甚至 1GB 的用户空间,因为您获得了 3GB 的用户空间。

我不知道 c 指针运算的细节,但我怀疑这些可能在某些编译器中比较为 <0。

关于c - 在 NULL 表示为 0 的平台上,编译器是否曾为 NULL <= p 生成意外代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7058176/

相关文章:

c++ - 从堆栈地址形成指针范围是未定义的行为吗?

c - 为什么这些构造使用前后递增的未定义行为?

c - C 中的运行时错误

c - 结构内存分配错误

python - 无法编译需要 C99 编译器 (AFAIU) 的 pyethash python 包。错误 - 无法打开包含文件 : 'alloca.h'

c++ - 在 C 和 C++ 中,使用逗号运算符(如 "a = b,++a;")的表达式是否未定义?

c - 应该调用什么函数 f() 来产生不同的东西?

c - 重新分配,字符**,段错误

c - 将结构的实例分配给新的 const 结构实例

c - const char * const 和 const char [] 有区别吗?