4

Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]

This question asks why

a[5] == 5[a]

It is answered in all aspects except one...

Why is one allowed to put an array subscript after an integer in the first place? And why isn't one allowed to write something like

[a]5

or

[5]a

or put [] in some other odd place?

In other words, what is the definition of where an array index operator is allowed?

EDIT I: The answers I received that quote the the standard were a little hard to grasp at first. But with the help of the responders I now understand. An array subscript (a square bracket) is allowed after a pointer or an integer. If it follows a pointer, what's inside the brackets must be an integer. If it follows an integer, what's inside the brackets must be a pointer.

I'm accepting the less upvoted answer because he did a bit more hand-holding in getting me to understand the quote from the standard. But the answer that strictly quotes the standard is correct too. It was just harder to understand at first.

EDIT II: I do not think my question was a duplicate. My question was about the allowed grammar regarding the array subscript operator. It was answered by quotes from the standard that never appear in the question I supposedly duplicated. It is similar, yes, but not a duplicate.

Community
  • 1
  • 1
John Fitzpatrick
  • 4,207
  • 7
  • 48
  • 71
  • 1
    Because the C standard explicitly says that `E1[E2]` is identical to `*(E1+E2)` and `+` is a commutative operator. – Alexey Frunze Oct 22 '12 at 19:17
  • 1
    That question answers your question: "In other words, what is the definition of where an array index operator is allowed? " "in C Programming Language (aka: K & R)". – m0skit0 Oct 22 '12 at 19:18
  • I dont quite see the answer. For example, can I legally write `7.3[b]`? And if not, why not? – John Fitzpatrick Oct 22 '12 at 19:22
  • @JohnFitzpatrick Array subscripts and all pointer arithmetic is done with integers and it's meaningless to use non-integers there if you think of it. You address integral values, not fractions like 1/10th of a bit. – Alexey Frunze Oct 22 '12 at 19:23
  • @JohnFitzpatrick No, you can't. If one of the operands of `+` is a pointer, the other shall have an integer type. `((int)7.3)["Harr Harr"]` should work, though. – Daniel Fischer Oct 22 '12 at 19:23
  • @m0skit0 The C programming language is defined by the standard, not by K&R. – Daniel Fischer Oct 22 '12 at 19:26
  • @DanielFischer: totally true, but the standard is based on K&R – m0skit0 Oct 22 '12 at 19:27
  • @AlexeyFrunze thanks. Ok, so non-ints are not allowed to be followed by square brackets. What about a struct? I guess I'm looking for the definition of where a square bracket is allowed. – John Fitzpatrick Oct 22 '12 at 19:27
  • @m0skit0 In a loose sense. It has evolved quite a bit since K&R. – Daniel Fischer Oct 22 '12 at 19:29
  • @DanielFischer goodness gracious. Im not going to even begin to try to grasp ` ((int)7.3)["Harr Harr"] ` today. But thanks for the thought food... – John Fitzpatrick Oct 22 '12 at 19:30
  • @JohnFitzpatrick How are you going to add a struct to a pointer or an integer? In what sense? Will you use its size, its address, its alignment, the number of fields in it, what? – Alexey Frunze Oct 22 '12 at 19:30
  • @AlexeyFrunze I dont want want to add a struct to a pointer or an integer. I want to know where I can legally put an opening square bracket in my code. – John Fitzpatrick Oct 22 '12 at 19:34
  • @JohnFitzpatrick Then it's best you get yourself a copy of the C standard. Or at least one of the freely available drafts of it. Really, you can ask questions like this indefinitely, but why? Just read the standard. And then if you don't find something in it, come back. – Alexey Frunze Oct 22 '12 at 19:36
  • It is actually answered in that question you linked, you just need to know what a commutative operator is. Asking about that would have been a better question perhaps. I'll vote to close this. – Lundin Oct 22 '12 at 19:37
  • @Lundin thanks. Actually I grasped the commutivity part. What was troubling me was that I always assumed a square bracket had to follow something that is a pointer of some sort. And 5 is not a pointer. But some of the answers seem to lead me to investigate the concept of a postfix expression. – John Fitzpatrick Oct 22 '12 at 19:41
  • @AlexeyFrunze thanks. I understand what you are saying about reading the standard. But I only use C from time to time and the standard is difficult to grasp for amateurs like me. I have read several C books over the years, and never encountered anything where a square bracket followed anything that wasnt some sort of pointer. So, I felt compelled to ask here where people who have read and understood the standard could help. And you have thanks. – John Fitzpatrick Oct 22 '12 at 19:53
  • @JohnFitzpatrick Sorry for not figuring out the question. It wasn't entirely obvious you were interested in this aspect of indexing. I will undo -1 if you edit somehow the question, perhaps add a disambiguation. Can't do that until the question is edited. – Alexey Frunze Oct 22 '12 at 20:11
  • @AlexeyFrunze I have made an attempt at a disambiguation. – John Fitzpatrick Oct 22 '12 at 20:17
  • That didn't do much. You should probably throw in `[E1]E2` as well. – Alexey Frunze Oct 22 '12 at 20:26
  • @AlexeyFrunze Please feel free to edit. I think you understand what Im asking, and Id like the post to be meaningful. – John Fitzpatrick Oct 22 '12 at 20:30
  • Why the question has been closed? I don't think it's a duplicate, the "possible duplicate" explain why 5[a] and a[5] are the same assuming 5[a] is allowed, not why 5[a] is allowed. Even if addition is commutative, if the grammar would not include that form it wouldn't be allowed, so "a + 5 == 5 + a" doesn't really answer the question. – effeffe Oct 23 '12 at 12:12

3 Answers3

6

Defined in the Array subscripting operator section of the C Standard here:

(C99, 6.5.2.1p2) "A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))."

and regarding the allowed types of E1 and E2:

(C99, 6.5.2.1p1) "One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall have integer type, and the result has type ‘‘type’’."

ouah
  • 142,963
  • 15
  • 272
  • 331
6

Postfix expression grammar from the C11 standard:

postfix-expression:
    primary-expression
    postfix-expression [ expression ]
    postfix-expression ( argument-expression-listopt )
    postfix-expression . identifier
    postfix-expression -> identifier
    postfix-expression ++
    postfix-expression --
    ( type-name ) { initializer-list }
    ( type-name ) { initializer-list , }

Primary expression grammar from the C11 standard:

primary-expression:
    identifier
    constant
    string-literal
    ( expression )
    generic-selection

And so on. 5 is an integer constant, so 5[a] match this:

postfix-expression [ expression ]

Hope this is what you mean.

EDIT: I forgot to mention this, but other comments already did:

One of the expressions shall have type ‘‘pointer to complete object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.

That 'integer type' it's needed to forbid non-sense floating-point constants subscripting.

effeffe
  • 2,821
  • 3
  • 21
  • 44
  • Yes thanks to you and ouah I now see that I need to grasp the concept of a postfix-expression. Off I go to learn... – John Fitzpatrick Oct 22 '12 at 19:32
  • I have to unaccept your answer for now because I am not able to see why `7.3[5]` is not a valid expression given the grammar you quote above. `7.5` is a constant, thus being a primary-expression. So what in the standard says that it cant be followed by a square bracket? – John Fitzpatrick Oct 22 '12 at 21:00
  • I wrote it, it's the last quote from the standard. There is not just the grammar, there are also "constraints" in the standard. As I wrote: "One of the expressions shall have type 'pointer to complete object type', the other expression shall have integer type"; 7.2 is not integer neither a pointer, it's a floating-point constant, so it's not a valid postfix-expression for the array subscript operator. A constraint is "restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted". – effeffe Oct 22 '12 at 21:22
  • OK, yes, now I get it. I'm a little slow. E1 and E2 must be a pointer and an integer in either order. Thanks for you patience. – John Fitzpatrick Oct 23 '12 at 06:50
2

a[5] translates to *(a+5). Addition is commutative, so a+5 = 5+a, which can be translated back to 5[a]. I agree it's a rather useless feature, but hell, why not?

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625