2

我试图理解 C99 sect 6.5.6 的第 8 和第 9 段(加法运算符)

第 8 段是否意味着:

int a [4];

int *p = a;
p --;      /* undefined behaviour */

p = a + 4; /* okay */
p --;      /* okay */
p += 2;    /* undefined behaviour */

p = a;
p += 5 - 5;    /* okay */
p = p + 5 - 5; /* undefined behaviour */

对于第 9 段,我的理解是 ptrdiff_t 总是大到足以容纳 2 个指针的差异。但是措辞:“只要值适合 ptrdiff_t 类型的对象”似乎表明这种理解是错误的。我的理解是错误的还是C99有别的意思。

您可以在此处找到标准草案的链接:http: //cboard.cprogramming.com/c-programming/84349-c-draft-standards.html

4

2 回答 2

2

我不认为你的解释是正确的。在我有(n1256)第9段的版本中:

如果结果在该类型的对象中不可表示,则行为未定义

这就对了。如果差异大于PRTDIFF_MAX或小于PTRDIFF_MIN行为未定义。

请注意,这给程序员带来了检查差异是否适合的负担ptrdiff_t。一个“惰性”平台实现可以只选择一个窄类型ptrdiff_t,让你处理它。

检查这一点并不是直截了当的,因为你不能在不引起 UB 的情况下进行减法。您必须使用两个指针指向同一对象内部(或刚刚超出)的信息以及该周围对象的边界在哪里。

于 2011-11-25T22:30:25.690 回答
0

我同意你对第 8 段的理解。标准说

如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。

似乎 C 假设数组内没有指针溢出,因此您可以在留在数组内时递增/递减指针。如果结果指针离开数组,则可能发生溢出并且行为未定义。

关于第 9 段,我猜该标准考虑到您可能有一个体系结构,它可以为您提供 32 位指针和 32 位数据类型,但由于两个 32 位指针的差异实际上是符号加 32 位(所以 33位),并非每个指针差异都可能匹配到 32 位 ptrdiff_t。对于 2 补充架构,这不是问题,但在其他架构上可能是一个问题。

于 2011-11-25T12:14:05.720 回答