Inside-Out Array-Indexing Syntax

J

Jonathan Burd

Greetings everyone,

I have noticed a little quirk in C's array-indexing syntax.
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).
The code follows:

#include <stdio.h>

#define A_MAX (5)

int
main (int argc, char ** argv)
{
int a[A_MAX] = {0, 1, 2, 3, 4};
int i;

for (i = 0; i < A_MAX; ++i)
printf ("%d\n", i[a]); /* <<-- inside-out */

return 0;
}

Any help will be appreciated.

Regards,
Jonathan.
 
E

Erik Trulsson

Jonathan Burd said:
Greetings everyone,

I have noticed a little quirk in C's array-indexing syntax.
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).
The code follows:

#include <stdio.h>

#define A_MAX (5)

int
main (int argc, char ** argv)
{
int a[A_MAX] = {0, 1, 2, 3, 4};
int i;

for (i = 0; i < A_MAX; ++i)
printf ("%d\n", i[a]); /* <<-- inside-out */

return 0;
}

Any help will be appreciated.

It is not quite clear what you are asking about, but I guess you are
wondering why a and i[a] are equivalent.
It is because a is just syntactic sugar for (*((a)+(i))) and x+y and
y+x are of course equivalent. Thus you get:

a == (*((a)+(i))) == (*((i)+(a))) == i[a]
 
J

Jonathan Burd

Erik said:
Jonathan Burd said:
Greetings everyone,

I have noticed a little quirk in C's array-indexing syntax.
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).
The code follows:

#include <stdio.h>

#define A_MAX (5)

int
main (int argc, char ** argv)
{
int a[A_MAX] = {0, 1, 2, 3, 4};
int i;

for (i = 0; i < A_MAX; ++i)
printf ("%d\n", i[a]); /* <<-- inside-out */

return 0;
}

Any help will be appreciated.


It is not quite clear what you are asking about, but I guess you are
wondering why a and i[a] are equivalent.
It is because a is just syntactic sugar for (*((a)+(i))) and x+y and
y+x are of course equivalent. Thus you get:

a == (*((a)+(i))) == (*((i)+(a))) == i[a]


Yes, I meant why a and i[a] are equivalent. Thanks. :)

Regards,
Jonathan.
 
L

Lawrence Kirby

Erik Trulsson wrote:
....
It is not quite clear what you are asking about, but I guess you are
wondering why a and i[a] are equivalent.
It is because a is just syntactic sugar for (*((a)+(i))) and x+y and
y+x are of course equivalent. Thus you get:

a == (*((a)+(i))) == (*((i)+(a))) == i[a]


The standard says of the [] operator

"One of the expressions shall have type ''pointer to object
type'', the other expression shall have integer type, and the result
has type ''type''."

It COULD have required the first expression to be a pointer and the second
an integer, and perhaps it should have. However C seems to have developed
historically allowing both orderings and that existing practice was
standardised.

Lawrence
 
A

Andrey Tarasevich

Jonathan said:
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).

It is not "included in the standard". It is simply "not excluded" from
the standard. This is nothing more than an innocent side effect of the
way the [] operator is defined in C (see other replies for more detailed
explanation).

Prohibiting this syntax would take extra effort. There is simply no
point in eliminating this harmless quirk of the language syntax.
 
M

Mike Wahler

Andrey Tarasevich said:
Jonathan said:
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).

It is not "included in the standard". It is simply "not excluded" from
the standard. This is nothing more than an innocent side effect of the
way the [] operator is defined in C (see other replies for more detailed
explanation).

Prohibiting this syntax would take extra effort. There is simply no
point in eliminating this harmless quirk of the language syntax.

But unless one is writing 'obfuscated code' intentionally, one
should prefer the more intutitive and readable form:

array_or_pointer_name[index_value]

-Mike
 
K

Keith Thompson

Jonathan Burd said:
Greetings everyone,

I have noticed a little quirk in C's array-indexing syntax.
I wonder what practical purpose this little "inverting" serves
to be included in the standard (it compiles fine with
gcc -pedantic -Wall -std=c89 and executes properly when run).
The code follows: [snip]
printf ("%d\n", i[a]); /* <<-- inside-out */
[snip]

This is question 6.11 in the C FAQ,
<http://www.eskimo.com/~scs/C-faq/faq.html>.

I've argued in the past that making pointer addition non-commutative
(allowing pointer+integer but banning integer+pointer) would have been
a good idea; it would have eliminated silly things like i[a] without
causing any real problems. But of course it can't be changed now
without breaking existing code (and it's not that big a deal anyway).
I wouldn't mind breaking i[a], but requiring all occurrences of
integer+pointer to be changed to pointer+integer could be a problem.

(If you disagree with me, you're in good company; plenty of people did
so when I suggested it before.)
 
C

CBFalconer

Mike said:
.... snip on a vs i[a] ...
Prohibiting this syntax would take extra effort. There is simply no
point in eliminating this harmless quirk of the language syntax.

But unless one is writing 'obfuscated code' intentionally, one
should prefer the more intutitive and readable form:

array_or_pointer_name[index_value]


There are cases when the so-called inverted notation is clearer.
For example, a database where the various fields are stored in
individual arrays, and the data base item is the actual index. Now
we may use item[fieldname] analagous with accessing a record named
item by item.fieldname.
 
L

Lawrence Kirby

It is not "included in the standard". It is simply "not excluded" from
the standard.

A distinction without a difference. The actual text of the standard is

"One of the expressions shall have type ''pointer to object type'', the
other expression shall have integer type, and the result has type
''type''."

The choice is explicit in the phrase "One of the expressions" and could be
"fixed" by shortening it to "The first expression".
This is nothing more than an innocent side effect of the
way the [] operator is defined in C (see other replies for more detailed
explanation).

There's nothing innocent about it. The wording of the standard is clearly
crafted to allow this possibility, it isn't something that just leaked
through by accident.
Prohibiting this syntax would take extra effort.

Not in the standard, probably not in a compiler. If it did require extra
effort it would be minimal. The standard is as it is because that was the
existing practice at the time. It was existing practice probably because
it seemed like a good idea at the time.
There is simply no
point in eliminating this harmless quirk of the language syntax.

Not now anyway.

Lawrence
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top