9

As I have learned, one can write the following code:

char *a = new char[50];
for (int i = 0; i < 50; ++i) {
    i[a] = '5';
}

It compiles. It works. It does exactly the same as

char *a = new char[50];
for (int i = 0; i < 50; ++i) {
    a[i] = '5';
}

Is it just because:

  • a[b] is implemented as a macro *(a + b) by default and the fact that both code samples are valid is just an accident/compiler specific
  • it's standardized somewhere and the outcome of such algorithms should be the same on every platform

It is reasonable to assume that addition should be commutative, but if we implement operator[] in that way, we have made something else commutative, what might not be what we wanted.

The interesting fact is that there is no pointer[pointer] operator, so operator[] is not a macro.

I know it's bad. I know it's confusing the people who read the code. But I want to know if it's just an accident and it will not work in a distant land where unicorns have seven legs and horns are on their left cheek.

Wolf
  • 9,679
  • 7
  • 62
  • 108
styrofoam fly
  • 578
  • 2
  • 9
  • 25
  • 17
    It's **not** a macro, it's a language rule. – stefan May 26 '14 at 14:48
  • I removed the C tag, since this seems rather C++-focused. – unwind May 26 '14 at 14:49
  • _'But I want to know if it's just an accident and it will not work in a distant land where unicorns have seven legs and horns are on their left cheek.'_ Unlikely, because the standard defines this behavior implicitely. – πάντα ῥεῖ May 26 '14 at 14:49
  • It does compile and run http://ideone.com/n91jfI. But I dont understand how. Right now I am befuddled. – Cool_Coder May 26 '14 at 14:51
  • 2
    check out http://bytes.com/topic/c/answers/504711-commutativity-operator – Agent_L May 26 '14 at 14:51
  • 4
    @Cool_Coder: It works because `a[i]` == `*(a + i)` == `*(i + a)` == `i[a]` – Blastfurnace May 26 '14 at 14:53
  • 6
    @Cool_Coder Just forget it. Anyone accessing first element in an array like this `0[a]` should be shot as soon as it is discovered. The only use of it is code obfuscation. – BЈовић May 26 '14 at 14:54
  • @Blastfurnace why did they allow such a confusing rule? I cannot understand a sane situation to use other than confusing the person debugging your code. – Cool_Coder May 26 '14 at 14:55
  • @Cool_Coder Why? If I remember correctly, I read somewhere that when C wasn't standardized, there were people accessing arrays like this `a[3]` and other people accessed like this `3[a]`, and they satisfied both kind of people by not breaking existing code. – BЈовић May 26 '14 at 14:59
  • @Cool_Coder: Array subscript syntax is just __pointer arithmetic__. See also BЈовић's comment above about shooting people that abuse it. – Blastfurnace May 26 '14 at 14:59
  • @BЈовић ohh so this originates from C. Looks to me like a cool interview question as they new generation of programmers might be aware of this...;) – Cool_Coder May 26 '14 at 15:01
  • @Blastfurnace I agree that under the hood its all pointer arithmetic. My point was that its confusing. Thats the reason why Perl died. I dont like it when a language says _There is more than one way of doing it_. Anyways understood from BЈовић's comment why it is allowed. – Cool_Coder May 26 '14 at 15:04
  • @user2420535, good for you, but we usually search for duplicates *before* asking :) – Frédéric Hamidi May 26 '14 at 15:10
  • @FrédéricHamidi I have searched, but it's hard to find something where language syntax is a key word. – styrofoam fly May 26 '14 at 15:11
  • @Cool_Coder That's a lousy interview question (at least unless you are interviewing for a C or C++ compiler implementor). That is a very edge-case language interpretation that no sane developer would voluntarily use. The only purpose for that as an interview question is to boost the ego of the interviewer, not to determine useful things about the interviewee. – Andre Kostur May 26 '14 at 16:43
  • @Andre Kostur In some cases ego of interviewee is considered useful. Actually our people interview new students and shot those kind of questions on them. Reaction: curiosity, attempt to investigate, arguing the point - says a lot about of personality of interviewee. Lack of actual knowledge on those "tricks" isn't held against them, lack of flexibility - may be. Our team strongly believes in people who can innovate or able to research the problem – Swift - Friday Pie Feb 02 '17 at 06:10

3 Answers3

13

C++ standard, § 8.3.4, note 7 (page 185) (emphasis mine).

Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.

user703016
  • 37,307
  • 8
  • 87
  • 112
4

Here is what C++11 standard has to say:

Note: Except where it has been declared for a class (13.5.5), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation. (emphasis is added).

So your assumption that a[b] is implemented as *(a + b) is correct, except that it is implemented directly in the compiler, not as a macro.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

The expression E1[E2] is identical (by definition) to *((E1)+(E2))

...and then commutativity of index and pointer takes hold. See your friendly neighbourhood C++ standard, section 5.2.1 in this version: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3485.pdf

pete23
  • 2,204
  • 23
  • 28