【发布时间】:2011-10-26 20:31:45
【问题描述】:
在 C99 中,相等 == 似乎永远不会未定义。如果将其应用于无效地址,它可能会意外生成1(例如,&x + 1 == &y 可能是偶然为真)。它不会产生未定义的行为。根据标准,许多(但不是全部)无效地址未定义以计算/使用,因此在p == &x 和p 中,或在&x + 2 == &y 中,无效地址会导致未定义的行为,而不是@987654328 @。
另一方面,>= 和其他比较在应用于不指向同一对象内的指针时是未定义的。这包括测试q >= NULL,其中q 是一个有效的指针。这个测试是我的问题的主题。
我从事低级嵌入式代码的静态分析器工作。这种代码做超出标准允许的事情是正常的。例如,在这种代码中,指针数组可以用memset(...,0,...) 初始化,尽管标准没有规定NULL 和0 必须具有相同的表示。为了有用,分析器必须接受这种东西并以程序员期望的方式解释它们。警告程序员会被视为误报。
所以分析器已经假设NULL 和0 具有相同的表示(您应该根据分析器检查编译器以确保它们同意这种假设)。我注意到一些程序将有效指针与 NULL 与 >= 进行比较(this library 是一个例子)。只要NULL 表示为0 并且指针比较被编译为无符号整数比较,就可以按预期工作。
我只希望分析器警告这一点,也许是因为一些积极的优化,它可能被编译成与程序员在传统平台上的意思不同的东西。因此我的问题是:在NULL 表示为0 的平台上,是否有任何程序没有将q >= NULL 评估为1 的示例?
注意:这个问题不是关于在指针上下文中使用 0 来获取空指针。关于NULL 表示的假设是一个真实的假设,因为memset() 示例中没有转换。
【问题讨论】:
-
如果您要初始化一个指针数组,为什么不直接使用
void *pointers[SIZE] = { NULL };(默认也将其余指针初始化为NULL)? -
@Chris Lutz 该构造声明并初始化。有时内存已经被保留,你只想初始化。
-
不知道
>= NULL的意义何在…… -
@Pascal Cuoq - 哦,好吧。我会使用上面的,然后使用
memcpy(dst, pointers, size_of_dst),但我认为将这样的事情强加给程序员是不好的,特别是对于嵌入式代码。 -
@pst 在 QuickLZ 中,比较是在循环中进行的。在第一次迭代中,其中一个指针为 NULL。对于以下迭代,它们都是输出缓冲区内的指针。但它当然可以替换为符合标准的
p == NULL || p <= q。
标签: c c99 undefined-behavior