Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does pointer arithmetic still work outside the array?

I am always reading that pointer arithmetic is defined as long as you don't leave the bounds of the array. I am not sure I completely understand what this means and I was a little worried. Hence this question.

Suppose I start with a pointer to the beginning of an array:

int *p = (int*) malloc(4 * sizeof(int));

Now I create two new pointers that lie outside the bounds of the array:

int *q = p + 10;
int *r = p - 2;

Now the pointers q-10, q-9, ..., r+2, r+3, and so on all lie inside the bounds of the array. Are they valid? For example, is r[3] guaranteed to give the same result as p[1]?

I have done some testing and it works. But I want to know if this is covered by the usual C specifications. Specifically, I am using Visual Studio 2010, Windows, and I am programming in native C (not C++). Am I covered?

like image 496
becko Avatar asked Aug 24 '12 03:08

becko


People also ask

Which operation Cannot be performed in pointer arithmetic?

Operations not possible with pointers These are: Addition of two pointer variables. Multiplication of a pointer with a constant value. Division of a pointer with a constant value.

Is pointer arithmetic faster than array indexing?

Pointer arithmetic is actually about 30% faster than using array indexes.

Why is pointer arithmetic not applicable on void?

Since void is an incomplete type, it is not an object type. Therefore it is not a valid operand to an addition operation. Therefore you cannot perform pointer arithmetic on a void pointer.


2 Answers

What you're doing works on the implementation you're using, as well as most popular implementations, but it's not conforming C. As chris cited,

§6.5.6/8: 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

The fact that it's undefined will probably become increasingly important in the future, with more advanced static analysis allowing compilers to turn this kind of code into fatal errors without incurring runtime cost.

By the way, the historical reason for subtracting pointers not within the same array being undefined is segmented memory (think 16-bit x86; those familiar with it will want to think of the "large" memory model). While pointers might involve a segment and offset component, a compiler could do the arithmetic just on the offset component to avoid runtime cost. This makes arithmetic between pointers not in the same segment invalid since the "high part" of the difference is lost.

like image 125
R.. GitHub STOP HELPING ICE Avatar answered Oct 22 '22 21:10

R.. GitHub STOP HELPING ICE


According to the C11 standard, §6.5.6/8 (I put in the first part for context):

When an expression that has integer type is added to or subtracted from a pointer
...
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.

Therefore, a result that is outside of the array and not one past the end is undefined behaviour.

like image 39
chris Avatar answered Oct 22 '22 21:10

chris