4

I've seen the explanations for pointer arithmetic (eg. Pointer Arithmetic). But I was wondering is there a real difference between:
Given:

int* arr = (int*) malloc(sizeof(int) * 3);

Does:

&(arr[1])

And:

arr + 1

Differ in any way, beside syntax. Is either technically more efficient? Is there certain context to use pointer addiction over the first? I saw the one example from Printing 1 to 1000 without loop or conditionals. Thanks in advance.

2
  • 4
    You don't need to cast the result of malloc in a C program. As to your question, you can just compile an example program and see for yourself. As others have answered, yes, they are the same. sizeof(3) is a bit weird, too. Commented Apr 9, 2013 at 1:17
  • Yea, meant do do that. Thanks for the catch. Commented Apr 9, 2013 at 1:23

2 Answers 2

5

&arr[1] and arr + 1 (and &1[arr]!) are identical, and all compute the same pointer. Per the C standard, §6.5.3.2:

The unary & operator yields the address of its operand....

...if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator.

Thus, per the specification, &arr[1] is to be evaluated as if it were written arr + 1.

Use of one over the other often comes down to preference. Personally, I like to use &arr[x] when I want to mean a pointer to just that element, and arr + x when I want to refer to an array starting at x.

Sign up to request clarification or add additional context in comments.

3 Comments

So in term of efficiency, they are essentially the same?
"Essentially", nothing. They are literally the same.
Liked both your answer, but I felt like Alexey went a little bit more in depth, but you answered the part of when to use either.
1

No, there's no difference, not even in performance (unless we're talking about compile times) because:

  • arr[1] is equivalent to *(arr + 1) and
  • in &(*(arr + 1)) neither the dereference nor the address operators do anything (the C standard says explicitly, the dereference doesn't occur in such cases), so the operators cancel each other out.

So, after the parsing and the AST building phases the compiler eventually ends up with just arr + 1 in both cases.

4 Comments

I'm actually curious -- can you show where in the C spec the dereference is specified not to happen?
@nneonneo: 6.5.3.2 Address and indirection operators: "If the operand is the result of a unary * operator, neither that operator nor the & operator is evaluated and the result is as if both were omitted, except that the constraints on the operators still apply and the result is not an lvalue."
Oh hey, the sentence right after that answers the question exactly: "Similarly, if the operand is the result of a [] operator, neither the & operator nor the unary * that is implied by the [] is evaluated and the result is as if the & operator were removed and the [] operator were changed to a + operator." Mind if I add that to my answer?
@nneonneo Or you could mention from the other part of the standard that E1[E2] is identical to (*((E1)+(E2))).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.