array equality trickiness

Hi,
I would appreciate, if someone explains me why is this true:

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;

int main()
{
    char* a[] = {"ABXC", "", "asd", "d"};
    int i = 2;
    
    if ( a[i] == *(a + i) )
        if ( *(i + a) == i[a] )
            cout << "equal" << endl;
    
    if ( a[i] ==  *(i + a))
        if ( *(a + i) == i[a] )
            cout << "equal" << endl;
    
    if ( a[i] == i[a] )
        if ( *(a + i) == *(i + a) )
            cout << "equal" << endl;
    
    return 0;
}
The [braket] operator is just a simplified/automated way to do pointer math.

a[0] is exactly the same thing as *a. Both simply dereference the 'a' pointer... they just use different operators to do so. By extension:

a[1] is the same as *(a+1). The latter simply adds 1 to the pointer before dereferencing. Therefore:

a[i[i][/i]] is the same as *(a + i). This is also the same as *(i + a) for the same reason 1+4 == 4+1

i[a], however, is not valid syntax (not unles 'i' is a pointer and 'a' is an integer, which in your above example, neither of those are the case). Your compiler should be throwing errors for you on line 17 of that code you pasted.
Last edited on
1
2
3
int array[] = { 1, 2, 3, 4, 5 };

cout << (3[array]) << endl;


is totally valid syntax. Why? Because Kernighan or Ritchie thought it would be cool to invert the array and index, I guess. Not that it has any practical use beyond that of obfuscated programming.

i[a] could look odd but it actually is valid syntax

http://www.cplusplus.com/forum/lounge/6205/
I stand corrected. I guess logically (to me) there's no reason why it should work (it's like trying to dereference an integer). But I guess if there's some weird C++ rule that says it's okay.... Personally I find that ridiculous.

Though I guess if you analyze the logic...
1
2
3
*(a + i) == a[i]      // if this is true
*(a + i) == *(i + a)  // and this is true
*(i + a) == i[a]      // then I guess by extension this is true? 


Apologies for my inaccurate statement. Though this still seems absurd to me.


EDIT -
hah -- apparently while I was typing Bazzy linked to a thread which explains it the exact same way. Haw.

I need to type faster.
Last edited on
It came from C. C++ is just being backwards compatible. I find it stupid also.
I guess the thing that trips me up about it is that in C++, brackets are an overloadable operator which act on the object outside of them. So i[a] would* throw a compiler error if 'a' is an object with [] overloaded.

*disclaimer: didn't actually test that -- not on my home computer and don't have easy access to a compiler right now. If that does work, though, I really would be dumbfounded.

Guess you learn something new every day! ^^
I was wondering that myself over dinner tonight, especially if the overloaded operator[] does not take an int. Have to try it out on my linux box later.
I think you could make that work on your objects too like:
1
2
3
class x;
int operator[](x obj, int i){return 10;}
int operator[](int i, x obj){return 9;}


edit:hmm operator[] must be a nonstatic member function. so that doesn't work
Last edited on
I tested using i[a] on visual studios and it threw an error. I'd say it's best to use the standard syntax for both human readability and portability.
See:


Not that it has any practical use beyond that of obfuscated programming.

Topic archived. No new replies allowed.