2

I am trying to understand paragraph 8 and 9 of C99 sect 6.5.6 (Additive operators)

Does para 8 mean:

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 */

For paragraph 9, my understanding had been that ptrdiff_t is always large enough to hold the difference of 2 pointers. But the wording: 'provided the value fits in an object of type ptrdiff_t' seems to suggest this understanding is wrong. Is my understanding wrong or C99 meant something else.

You can find a link to the draft standards here: http://cboard.cprogramming.com/c-programming/84349-c-draft-standards.html

Mat
  • 202,337
  • 40
  • 393
  • 406
tyty
  • 839
  • 5
  • 12

2 Answers2

2

I don't think your interpretation is correct. In the version I have (n1256) paragraph 9 states:

If the result is not representable in an object of that type, the behavior is undefined

that is it. If the difference is larger than PRTDIFF_MAX or smaller than PTRDIFF_MIN the behavior is undefined.

Notice that this places the burden on the programmer to check if the difference fits in ptrdiff_t. A "lazy" platform implementation could just choose a narrow type for ptrdiff_t and leave you dealing with that.

Checking for that would not be straight forward since you can't do the substraction without provoking UB. You'd have to use the information that the two pointers point inside (or just beyond) of the same object and where the boundaries of that surrounding object are.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

I agree to your understanding of paragraph 8. The standard says

If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

It seems that C assumes that there is no pointer overflow inside an array, so you can increment/decrement pointers while you stay inside the array. If the result pointer is leaving the array, an overflow might occur and behaviour is undefined.

Regarding paragraph 9 I guess the standard takes into account that you might for example have an architecture that gives you 32 bit pointers and 32 bit data types, but since the difference of two 32 bit pointers in fact is a sign plus 32 bit (so 33 bits), not every pointer difference might match into a 32 bit ptrdiff_t. With 2 complement architecture this is not a problem, but it might be a problem on other architectures.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • Actually, the standard **mandates** that there is no pointer overflow inside the array, or indeed if you go one element beyond the end of the array, although in this last case, you cannot dereference the pointer. – JeremyP Nov 25 '11 at 15:20
  • Why do you think that with twos complement there is no problem? The space of the possible values is simply too large to fit in a 32 bit quantity. You'd always have to keep track of the sign additionally. – Jens Gustedt Nov 25 '11 at 22:09