cpointerslanguage-lawyerpointer-arithmetic

What do these quotes say about pointer arithmetic?


No matter how hard I try, I can't understand these two quotes in C Standard:

If the pointer operand is not null, and the pointer operand and result do not point to elements of the same array object or one past the last element of the array object, the behavior is undefined.

C23(6.5.7 #9)

And:

Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.7).

C23(J.2 #41)

1)Does this mean that the following address has undefined behavior?:

int m[10] = {0,1,2,3,4,5,6,7,8,9};
int * p = m + 100;

2)And no matter how they explain it to me, I also can't understand the following; The Standard says that a pointer can point to the first element after the end of the array.But can't we point to 100 or 200 elements after the end of the array? Is it written in the C Standard?If so, please provide these quotes!

EDITED:

3)And what will happen in this case:

int m[10] = {0,1,2,3,4,5,6,7,8,9};
int * p = m + 10,*mp = m + 12;
int a = mp - p;

Will a be equal to 2?.If so, why?

Thank you in advance!


Solution

  • The above quotes state that, given a pointer to an element of an array, that any arithmetic performed on that pointer is required to point either to another array element or to one element past the end of the array.

    1)Does this mean that the following address has undefined behavior?:

    int m[10] = {0,1,2,3,4,5,6,7,8,9};
    int * p = m + 100;
    

    Correct. p points 100 elements into an array of size 10, which is more that one element past the end, so the second line triggers undefined behavior. Had you added a value between 0 and 10 inclusive, that would be well-defined.

    2)And no matter how they explain it to me, I also can't understand the following; The Standard says that a pointer can point to the first element after the end of the array.But can't we point to 100 or 200 elements after the end of the array? Is it written in the C Standard?If so, please provide these quotes!

    The first passage you quoted says precisely that:

    If the pointer operand is not null, and the pointer operand and result do not point to elements of the same array object or one past the last element of the array object, the behavior is undefined.

    In the above code example, the result of m + 100 does not point to an element of the array m or one past the end. It instead attempts to point well past that. Therefore, it is undefined behavior as per the above passage.

    3)And what will happen in this case:

    int m[10] = {0,1,2,3,4,5,6,7,8,9};
    int * p = m + 10,*mp = m + 12;
    int a = mp - p;
    

    Will a be equal to 2?.If so, why?

    The value of p is valid as it points to one element past the end of the array m. However, the initializer of mp, i.e. m + 12 does not point to an element of m or one past the end, so that triggers undefined behavior.

    Nothing that happens after that point matters because of the prior undefined behavior. And in fact, what happened before can't be depended on either. See this question for more detail.