

a[5] == 5[a] - stephth
http://stackoverflow.com/questions/381542/in-c-arrays-why-is-this-true-a5-5a

======
mkelly
Warning: crazy rant coming.

So this is what HN has degenerated to? I'm sorry, but I remember eagerly
reading the front page, learning things from interesting articles, and -- more
importantly -- reading well-written commentary from people far more
accomplished than I. I lurked, because I couldn't contribute at the level that
most of the regular commentors could, but I learned a great deal.

HN has retained its preoccupation with not being reddit (which is noble), but
has not retained the quality to justify it.

Great communities are transient, and HN is probably what taught me that. I
have nothing but respect for pg, and for the community that once populated HN.

Peace. I'm out.

Crazy rant done.

~~~
5hoom
Your finding the articles less interesting could be a function of you becoming
more knowledgable yourself, therefore there is less "low hanging fruit" with
regards to new knowledge for you to acquire.

Might be a sign that it's time for you to start posting some well-writen
commentary yourself ;)

~~~
djcapelis
Dude mkelly has known why a[5] and 5[a] were the same damn thing since before
there was an HN. Stop making bad assumptions, he's telling a true story. I'm
sorry to see him leave just as I realized he was here. Oh well.

He's not the only one saying these things. It's just how it is. After awhile,
what was is no more. HN stood longer than most.

~~~
djcapelis
I'm sorry, but I'm happy to get voted down for my tone for once. I remember a
time when one could assume that people around HN had a basic CS education and
the community didn't get fascinated by stack overflow threads about how C
works because we were all thinking about crazy interesting things.

I think anyone who says that people don't have a right to miss that and
assumes that there is no problem is part of the problem.

------
biot
Trying to intuit how a language works tends to be problematic. To understand
this operation, you need to look it up in the spec: <http://www.open-
std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>

Section 6.5.2.1 "Array Subscripting" states in item (2) under "Semantics" on
page 70:

    
    
      A postﬁx expression followed by an expression in square brackets []
      is a subscripted designation of an element of an array object. The
      deﬁnition of the subscript operator [] is that E1[E2] is identical
      to (*((E1)+(E2))). Because of the conversion rules that apply to
      the binary + operator, if E1 is an array object (equivalently, a
      pointer to the initial element of an array object) and E2 is an
      integer, E1[E2] designates the E2-th element of E1 (counting from
      zero).
    

In other words:

    
    
      a[5] is equal to (*((a)+(5)))
      5[a] is equal to (*((5)+(a)))
    

So what are the rules for E1+E2? Refer to section 6.5.6 "Additive Operators",
item (8) under "Semantics" on page 83:

    
    
      When an expression that has integer type is added to or subtracted
      from a pointer, the result has the type of the pointer operand. If
      the pointer operand points to an element of an array object, and
      the array is large enough, the result points to an element offset
      from the original element such that the difference of the subscripts
      of the resulting and original array elements equals the integer
      expression. In other words, if the expression P points to the i-th
      element of an array object, the expressions (P)+N (equivalently, 
      N+(P)) and (P)-N (where N has the value n) point to, respectively,
      the i+n-th and i−n-th elements of the array object, provided they
      exist.
    

In other words, if (P)+N is equal to N+(P), you need only substitute "a" for
"P" and "5" for "N" and that proves a[5] == 5[a]. If I've missed something,
corrections are welcomed.

~~~
Someone
Given that these are separate sections in the C spec, would

    
    
      &12[5] == 17
    

(ignoring OS memory protection)?

~~~
biot
The constraints section of 6.5.2.1 requires that one expression be a pointer.
If you cast one of those numbers to a byte pointer with its address at the
numerical location in memory, I don't see why it wouldn't result in a pointer
to memory location 0x00000017. Give it a shot!

------
guyzero
I suppose this is an evergreen topic for new C programmers. I find it
surprising that HN is posting something that's basically a verbatim quote from
K&R which was first published in 1978. a 33 year-old C hack ain't news.

Than again, I guess the days where you could assume everyone who knew how to
program programmed in C are long gone.

~~~
pyre
You're also assuming that everyone that knows how to program in C has read
K&R. That's like assuming that everyone that knows how to program has read the
Art of Computer Programming.

~~~
comatose_kid
Interesting comparison! Let's take a look:

TAOCP Vol 1 Amazon rank: 364,370. K&R C Amazon rank: 2307

Based on the above, and also that C programmers are a subset of everyone that
knows how to program, it seems that the two ratios would be off by a few
orders of magnitude. So I don't think this comparison is really correct.

I'll add to this my anecdotal experience that about half of the people I have
worked with who call themselves C programmers have read K&R.

------
pyre
That explanation only partially works.

    
    
      a[5]
    

evaluates to something like:

    
    
      *(a + (sizeof(a) * 5))
    

so shouldn't

    
    
      5[a]
    

evaluate to

    
    
      *(5 + (sizeof(5) * a))
    

Those don't seem equivalent, unless I'm missing something.

~~~
lurker19
As noted in the SO comments: when compiling the "+", the compiler uses the
sizeof of the referenced type of whichever addend is actually a pointer.

~~~
pyre
I think that I've been away from statically-typed languages for too long. I
was just thinking of the pointer as an int whose value just happens to be a
memory address and forgetting that the compiler knows it's a pointer.

~~~
lurker19
This works just as well in dynamically typed language by using your language's
version of .getClass() or instanceof. It would just happen at runtime instead
of compile time.

It only wouldn't work in very weakly typed languages like ... assembler?

~~~
pyre
I was evaluating 5 + a to mean int + int, because the pointer is stored in an
int. Maybe I should have just stated, "It's been awhile since I've work with
pointers." Most dynamic languages don't have a concept of pointers, or at
least not pointer math.

------
tzs
It's more amusing for multi-dimensional arrays:

    
    
       a[x][y] = y[x[a]]
       a[x][y][z] = z[y[x[a]]]
    

and so on.

------
kqueue
C 101.. HN is becoming sillier every day.

------
program
I've read this example first time in a storic stackoverflow topic:

[http://stackoverflow.com/questions/1995113/strangest-
languag...](http://stackoverflow.com/questions/1995113/strangest-language-
feature)

it will stay forever in my bookmarks.

------
bnegreve
Ok, the "interesting" thing is this expression is that 5 is accepted as a
variable identifier although it does not meet the requirements to be one. The
fact that the expression evaluate to a result that turns to be correct is not
so relevant.

~~~
lurker19
I think you mean "pointer type", not "variable". 0xblah could very well a be
valid pointer value.

Anyway, Array subscripting (brackets) is not an operator in C. It is just
syntactic sugar. This is different from C++ (but even in C++, C compatibility
is maintained for primitives) .

------
jc-denton
Old! C programmers know how this is expanded.

