For example consider:

int index = 3;
int array[4] = {0, 1, 2, 3};

then both index[array] and array[index] are valid expressions, much like *(index + array) and *(array + index).

In C arrays why is this true? array[5] == 5[array] explains how it works. My question is: Why did the language designers choose to allow this? Why not just enforce that index[array] is invalid, for clarity's sake?

  • 1
    Note that prohibiting index[array] would likely introduce another page or two to the spec. The current syntax can be described in a line.
    – Pubby
    May 3, 2012 at 15:16

6 Answers 6


First of all, it would help to read dmr's Development of the C Language to get some insights into some of C's quirks, particularly when it comes to array semantics (basically, blame BCPL and B for most of it).

As for the question "[w]hy not just enforce that index[array] is invalid, for clarity's sake," what would such a check buy you in exchange for the cost of performing it? The form almost never appears outside of the IOCCC, so it's not like it's a major problem in production code (compared to the use of, say, gets, or unchecked array accesses (which disallowing i[a] won't help with), or <fill in the blank>). It's not a bug; it doesn't introduce any undefined behavior; it doesn't introduce any security holes not already present with a[i]; the only complaints against it are stylistic in nature.

It's like asking why both T *p and T* p are valid; there is no "why" beyond it being an accident of the language syntax. There's nothing deliberate behind allowing both, it's just a function of how the grammar works. Same with a[i] and i[a]. Professional programmers are (usually) grown-ups, and don't deliberately introduce confusion where it isn't warranted, so most will naturally use a[i].

You're basically trying to guard against a problem that doesn't really exist.


The choice to use array[index] was probably made to follow mathematical convention and the precedent set for arrays by other languages like ALGOL, FORTRAN, and BASIC (the latter two use parentheses instead of brackets). That decision does make the operator an odd duck because it's binary operator but requires that you throw in an additional token after the right-hand expression.

The operator could just as easily have been a single character (@ isn't spoken for in C, so let's call that the "pointer addition operator"). Because, as David Thornley's answer in the aforementioned SO question points out, pointer addition is commutative, a @ 5 and 5 @ a make equal sense. (C forerunner BCPL used ! for this.)

In some ways it's natural to look at the array operator as behaving like a function, which makes sense in the context of languages that do f(x) to call a function and a(i) to access an array. Since operators in C don't work that way, you have to think of it as a commutative, binary operator with baggage.

  • I like the explanation, a slightly more formal one might include that arrays are merely a syntactical sugar of pointers which further reinforces your commutative argument.
    – sdg
    May 2, 2012 at 20:26

According to James Curran the reason for this was that when C was developed, computers were slower + had less memory, so such checks and optimizations were not worth the cost.


  • 1
    It would be a compile-time check (is the left operand of a pointer type?), so it wouldn't have mattered much. It wouldn't have ruined the one-pass guarantee either. Of course, a half-assed 70's compiler might even ignore that, but the 70s were very early in C's evolution -- plenty of time to deprecate it or to teach compilers to shun it.
    – user7043
    May 2, 2012 at 17:49
  • 4
    @delnan: Compile time was still a big thing back in the beginning of C so I would say it did matter (though personally I would not go as far as to say that was the reason). May 2, 2012 at 19:34

We may never know for certain why the feature was allowed in the first place, but it stands to reason that it remains in the language today for backward compatibility with older versions of the language. There's no obvious and compelling reason to remove it, so it doesn't make sense to gratuitously break existing code.


It's sort of like asking why people would design cars that can hit pedestrians. They don't. They design cars to do what their drivers tell them to do. C was designed with the crazy, arcane notion that programmers are in charge of their own programs, and if they write something stupid in a programming language, it's their own responsibility. Design decisions erred on the side of removing programmer restrictions.

  • 1
    Your approach is an argument for why it doesn't need to be changed, but it doesn't answer the question of how it got that way. index[array] isn't an unintended, emergent behavior. It was deliberately put into the language, so it's reasonable to ask why.
    – octern
    May 3, 2012 at 0:41
  • 1
    @octern - see my answer above. It is an emergent behavior that falls out of the array subscripting semantics (i.e., E1[E2] == *((E1)+(E2))); the only constraint is that one of E1 or E2 be a pointer expression, and the other be an integral expression. There's no constraint that E1 always be the pointer expression and E2 always be the integer expression. Such a constraint could be added, but since almost nobody uses the second form outside of the IOCCC, there's little to no benefit for the cost of performing the check.
    – John Bode
    May 3, 2012 at 14:53

Because, like several other features of C, it just wasn't thought through. I doubt anyone was really thinking about the mathematical logic behind array fetching in memory. As it turns out, though, both operations result in the same math (basically).

And Mr. Curran might say that, but I'd guess it didn't have a lot to do with computation cost. I could be wrong though.

  • 1
    -1 for random editorializing on the motivations of the C designers
    – sdg
    May 2, 2012 at 20:24
  • I'll randomly editorialize on whatever I feel like, thank you. Especially when I'm correct. May 2, 2012 at 21:01
  • 3
    You're correct: you could be wrong.
    – Blrfl
    May 3, 2012 at 0:28
  • Yeah, that comment was pretty constructive, right? May 4, 2012 at 14:50

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.