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.

Community
  • 1
  • 1
SGM1
  • 968
  • 2
  • 12
  • 23
  • 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. – Carl Norum Apr 09 '13 at 01:17
  • Yea, meant do do that. Thanks for the catch. – SGM1 Apr 09 '13 at 01:23

2 Answers2

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.

nneonneo
  • 171,345
  • 36
  • 312
  • 383
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.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • I'm actually curious -- can you show where in the C spec the dereference is specified not to happen? – nneonneo Apr 09 '13 at 01:32
  • @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." – R.. GitHub STOP HELPING ICE Apr 09 '13 at 01:34
  • 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 Apr 09 '13 at 01:36
  • @nneonneo Or you could mention from the other part of the standard that `E1[E2] is identical to (*((E1)+(E2)))`. – Alexey Frunze Apr 09 '13 at 01:46