Obviously both &a[i]
and a+i
return int*
. The question is whether they are performed in the same way, since there are two operators in &a[i]
but only one operator in a+i
?
-
Everything is resolved in the first optimizing phase of compiler: The name of an array object is used as the address of the first element of array, then is added the index using the standard pointers arithmetic. – Frankie_C Apr 14 '18 at 15:55
-
2the number of operators isn't relevant here. [`a[b]` and `*(a + b)` are the same](https://stackoverflow.com/a/381549/995714) – phuclv Apr 14 '18 at 15:56
-
3https://godbolt.org/g/gncewv – tkausl Apr 14 '18 at 15:56
-
I think is an idiom question, For myself, I prefer `a + i`. – Stargateur Apr 14 '18 at 16:04
-
`&a[i]` and `a+i` translate to the exact same thing, it's just different syntax for the same thing. And I prefer `a + i`, for me that's more readable than `&a[i]` – Pablo Apr 14 '18 at 16:07
2 Answers
In C, they are identical. The C standard defines a[i]
to be the same as *(a + i)
, so &a[i]
is just &*(a + i)
which is a + i
. (The surprising consequence of this is that you could just as easily write i[a]
.)
The number of operators has no real significance here.

- 205,541
- 37
- 345
- 415
Historically, technically, given int a[10];
, &a[10]
used to be technically invalid because it dereferenced a pointer past the end of an array, whereas a+10
has always been valid.
Nowadays: a[i]
is defined as *(a+i)
, so &a[i]
means &*(a+i)
. When a
is an array or a pointer, and i
is an integer, then yes, that is equivalent to a+i
. When both &
and *
are applied to the same pointer expression, they are now specifically specified to have no effect.
More details for those interested in the history: this is the text that was added in C99.
6.5.3.2 Address and indirection operators
3 [...] 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.
This text was not there yet in C89/C90, so the rule that a pointer subjected to the *
operator has to actually point to an object or function still technically applied. The standard was changed specifically to make such constructs valid.
-
2
-
@DietrichEpp In C89/C90. C99 added the rule that `&*p` doesn't actually dereference `p`. – Apr 14 '18 at 16:00
-
1@Stargateur Why is a comparison between the different revisions of the C standard not relevant for this question, especially considering how many compilers never adopted C99, let alone C11? – Apr 14 '18 at 16:10
-
@hvd Well, your answer is interesting but I don't think the question ask that. Plus there is only one C standard and it's C11, all compilers that doesn't implement it, can't be call C compiler ;) (yes I talking to you microsoft). Howevern if you can keep going and talk about the idiom difference between there two construct (that lead to C99 to add this rule) I will probably upvote your answer ;) – Stargateur Apr 14 '18 at 16:14
-
@Stargateur there are most definitely more C standards. C11 is just the most recent at the moment. On a real C compiler (yes, that excludes MSVC) you can specify the standard to compile the code in e.g. `-std=c90` `-std=c11` – bolov Apr 14 '18 at 16:16
-
4@Stargateur Answering the question and providing additional information as well is fine on SO. The question didn't ask about `i[a]` either, but I don't think there's anything wrong with Dietrich Epp choosing to include that in his answer. – Apr 14 '18 at 16:16
-
1And I find the history of this and how this specific issue changed over the standards very interesting. And definitely on topic. – bolov Apr 14 '18 at 16:17
-
-
@Stargateur and regarding MSVC ... dude... I agreed with you ... that's exactly what I said ... – bolov Apr 14 '18 at 16:21
-
@bolov Sorry about the spam of this answer, but here the link, https://port70.net/~nsz/c/c11/n1570.html#Forewordp6, "C99 code and C99 compilers anymore", I say it's not C standard. There are just other standard but not C standard. – Stargateur Apr 14 '18 at 16:23
-
I found it at the same time :p. Yes, but this is so that you don't prove something in the current standard with quotes from the previous standard. As in this standard doesn't built upon the previous one, but rather replaces it. You can't just close your eyes and say there are no C99 code and C99 compilers anymore. – bolov Apr 14 '18 at 16:26
-
@Stargateur What does that mean, according to you, for the C++ standard, which includes C99 in its normative references? I can say one thing for sure: all C++ implementors take it to mean they have to conform to the relevant bits of C99, not C11 or any later version of the standard. – Apr 14 '18 at 16:28
-
@hvd C++ standard is allow to reference C99, that nothing to do with C standard. The important point is there is only one C standard and it's C11, all other are just other standard. Like there is only one python standard and it's python 3, python 2 is just a standard but not "python standard". This is a importante concept to avoid this kind of thing like "I don't care I will stay forever to C89" ;) and C committee have all right to statute about what is C standard. – Stargateur Apr 14 '18 at 16:30
-
@Stargateur Ah, I had to read that a couple of times to make sure I got what you meant. That's not an unreasonable position, but at the same time, right or wrong, the "C", "ANSI C" and "ISO C" names will undoubtedly continue to be applied to implementations which do not conform to C11. I prefer to stick with a position that more closely corresponds to that practice. – Apr 14 '18 at 16:49
-
1@Stargateur: Honestly, I find it difficult to interpret your comments here charitably. “There is only one C standard” is a fine if you use a certain definition for the word “standard”, but demanding that other people only use your definition that word in other contexts is more than just unreasonable, it’s annoying and it derails an interesting conversation about history (how has the C standard changed) into pedantry over whether you should call C90 a “standard”. I would be inclined to call C90 an “obsolete standard” but arguing that it is not a standard just seems hostile and pointless. – Dietrich Epp Apr 14 '18 at 19:25
-
@DietrichEpp I never say C90 is not a standard... again that amazing how people don't read what other people write, I say C90 is not the C standard. "but demanding that other people only use your definition that word in other contexts is more than just unreasonable"... are you serious, word are important if we don't agree about the definition we can't communicate, it's very important and it's not "my" definition but the definition of the C committee ! Sorry if I'm being too rude in my comment. – Stargateur Apr 14 '18 at 19:31
-
@Stargateur: You say that "there is only one C standard and it's C11", you also say you "never say C90 is not a standard". I am not sure of a reasonable way to reconcile these two claims. I am curious what you claim the C committee's definition of "standard" is... is there a citation you can provide that describes what the word "standard" means to the C committee? – Dietrich Epp Apr 14 '18 at 21:53
-
@DietrichEpp As I understand it, he's saying C90 is a standard, but it is not a/the C standard, that the term "C standard" can only be applied to the current version. It had taken me several re-reads to get that understanding and as mentioned I do not share that point of view, but I do not see an inconsistency in it. – Apr 14 '18 at 22:05
-
C90 is *not a standard*. It is the first edition of *the standard* "ISO/IEC 9899". It was *the* standard until it was amended, after which it was *the standard* with the amendments. It has now been cancelled. You cannot usually even get documents for obsolete standard editions from the standard bodies. The current standard for C programming is ISO 9899:2011. – Antti Haapala -- Слава Україні Apr 15 '18 at 11:01