C指针加减昆虫。 6.5.6

时间:2011-11-25 11:05:17

标签: c pointer-arithmetic

我试图理解C99第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

2 个答案:

答案 0 :(得分:2)

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

  

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

就是这样。如果差异大于PRTDIFF_MAX或小于PTRDIFF_MIN,则行为未定义。

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

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

答案 1 :(得分:0)

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

  

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

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

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