6

Recently I saw an answer on a question where they explained that addressing arrays in this way <number>[array] is valid C code. How do square brackets work in C?

Example:

char x[] = {'A','B','C','D','E','F','G','H','I','J'};
printf("%d\n",5[X]);
//Will print 70 == 'F'

This kind of notation seems cumbersome and potentially confusing for everybody including the author.

Does this way of addressing arrays come with some justifiable advantage?

or

Can I continue with my life without worrying?

alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • It's a cute trick used in obfuscated C contests. Don't use it in serious code even if the syntax allows for it. – Shawn Jun 20 '19 at 09:53
  • It is purely an opinion based question. – kiran Biradar Jun 20 '19 at 09:53
  • http://c-faq.com/aryptr/joke.html – David Ranieri Jun 20 '19 at 09:55
  • Voted to close as primarily opinion-based (though I think most people have the same opinion) – pmg Jun 20 '19 at 09:55
  • 2
    Even if how to style your code is it's a matter of opinion, there are legitimate reasons to use certain syntax over others. Hence the question. – 7PintsOfCherryGarcia Jun 20 '19 at 09:55
  • 5
    @kiranBiradar i disagree. Universal advises regarding Clean Code are rarely purely opinion based. There are no benefits but only disadvantages using this syntax, thus its objectively bad. Plus, OP didnt ask whether its good. OP asked whether is has any advantages. – Fureeish Jun 20 '19 at 09:55
  • 1
    @kiranBiradar I disagree. OP is explicitly asking for justifications. Given that this syntax is explicitly legal it’s a valid question. (And the answer is that there’s not even a valid reason for this to be legal. The authors of C just wanted to be clever: There’s no reason for subscript operations to support commutative syntax) – Konrad Rudolph Jun 20 '19 at 10:04
  • 1
    @kiranBiradar It's most definetely not. It's possible that the answer is "there are no objective cons and pros" but that's an objective answer. – klutt Jun 20 '19 at 10:04
  • Not sure if this question adds anything to the canonical question: https://stackoverflow.com/questions/381542/with-arrays-why-is-it-the-case-that-a5-5a – Ruud Helderman Jun 20 '19 at 10:26
  • 1
    @RuudHelderman I think it does. – klutt Jun 20 '19 at 10:57
  • 1
    C doesn't generally actively forbid things there's no technical reason to forbid. This "feature" basically exists because of the interplay of other language features. But *if* you can find a valid reason to use it, good for you! C will get out of your way and let you use it. – Alex Celeste Jun 20 '19 at 11:23
  • 1
    Related: [Do pointers support “array style indexing”?](https://stackoverflow.com/questions/55747822/do-pointers-support-array-style-indexing) – Lundin Jun 20 '19 at 11:31
  • A user on quora.com plagiarized this question: https://www.quora.com/Is-there-any-justification-for-addressing-an-array-like-number-array I've reported it there. – Keith Thompson Jun 20 '19 at 20:01

3 Answers3

7

I have never encountered this in "real code" (i.e., outside of intentionally obfuscated things and puzzles with artificial limitations) so it would seem that it is quite universally agreed that this shouldn't be done.

However, I can come up with a contrived example where it might be considered by some (not necessarily me) a nicer syntax: if you have multiple pieces of data related to a single entity in a column, and you represent the rows as different arrays:

enum { ADA, BRIAN, CLAIRE };
const char *name[] = { "Ada", "Brian", "Claire" };
const unsigned age[] = { 30, 77, 41 };

printf("%s is %u years old\n", ADA[name], ADA[age]);

I will be the first to agree that this obfuscates the syntax by making it look like the people are the arrays instead of being the indexes, and I would prefer an array of struct in most cases. I think a case could be made for this being nicer-looking, though, or perhaps in some cases it would be a way to swap the rows and columns (arrays and indexes) with minimal edits elsewhere.

Arkku
  • 41,011
  • 10
  • 62
  • 84
  • 3
    I think the most dangerous thing about this is the fact that it looks reasonable. :D – klutt Jun 20 '19 at 11:35
  • 2
    Hm, interesting use case... Assuming a special architecture with ROM and RAM, and data sets with const and mutable members. With structs, we'd need to place all of into RAM, with separate arrays, we could place the const part into ROM and leave only the mutable parts in RAM... – Aconcagua Jun 20 '19 at 15:53
  • 1
    This is almost like the beginning of an entity-component design; in particular, using structure-of-arrays, it's possible to add "fields" to `ADA` and friends without affecting the layout of the data that currently exists. This actually looks quite elegant, to me. – Alex Celeste Jun 20 '19 at 15:56
6

As far as I can tell, there are no technical pros or cons with either method. They are 100% equivalent. As the link you provided says, a[i] = *(p+i) = [addition is commutative] = *(i+p) = i[a].

For subjective pros and cons, well it's confusing. So the form index[array] is useful for code obfuscation, but other than that I cannot see any use of it at all.

One reason (but I'm really digging here) to use the standard way is that a[b+c] is not equivalent to b+c[a]. You would have to write (b+c)[a] instead to make it equivalent. This can be especially important in macros. Macros usually have parenthesis around every single argument in every single usage for this particular reason.

It's basically the same argument as to write if(2==x) instead of if(x==2). If you by accident write = instead of == you will get a compiler error with the first method.

Can I continue with my life without worrying?

Yes.

klutt
  • 30,332
  • 17
  • 55
  • 95
2

Yes, the pointer arithmetic is commutative because addition is commutative. References like a[n] are converted to *(a+n) but also n[a] is converted to *(n+a), which is identical. If you want to win ioccc competitions you must use this.

alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • You’ve explained why pointer arithmetic is commutative. You have *not* explained why array subscripting is commutative: It may be *semantically* equivalent to pointer arithmetic + dereferencing but clearly it’s not *syntactically* equivalent. – Konrad Rudolph Jun 20 '19 at 10:13