C++ array[index] vs index[array]

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

Is the possibility of both array[index] and index[array] a compiler feature or a language feature. How is the second one possible?


The compiler will turn

index[array]

into

*(index + array)

With the normal syntax it would turn

array[index]

into

*(array + index)

and thus you see that both expressions evaluate to the same value. This holds for both C and C++.


From the earliest days of C, the expression a[i] was simply the address of a[0] added to i (scaled up by the size of a[0]) and then de-referenced. In fact, all these were equivalent:

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

====

The only thing I'd be concerned about is the actual de-referencing. Whilst they all produce the same address, de-referencing may be a concern if the types of a and i are different.

For example:

    int i = 4;
    long a[9];
    long x = a[i]; //get the long at memory location X.
    long x = i[a]; //get the int at memory location X?

I haven't actually tested that behavior but it's something you may want to watch out for. If it does change what gets de-referenced, it's likely to cause all sorts of problems with arrays of objects as well.

====

Update:

You can probably safely ignore the bit above between the ===== lines. I've tested it under Cygwin with a short and a long and it seems okay, so I guess my fears were unfounded, at least for the basic cases. I still have no idea what happens with more complicated ones because it's not something I'm ever likely to want to do.


As Matthew Wilson discusses in Imperfect C++, this can be used to enforce type safety in C++, by preventing use of DIMENSION_OF() -like macros with instances of types that define the subscript operator, as in:

#define DIMENSION_OF_UNSAFE(x)  (sizeof(x) / sizeof((x)[0]))

#define DIMENSION_OF_SAFER(x)  (sizeof(x) / sizeof(0[(x)]))

int ints[4];

DIMENSION_OF_UNSAFE(ints); // 4
DIMENSION_OF_SAFER(ints); // 4

std::vector v(4);

DIMENSION_OF_UNSAFE(v); // gives impl-defined value; v likely wrong
DIMENSION_OF_SAFER(v); // does not compile

There's more to this, for dealing with pointers, but that requires some additional template smarts. Check out the implementation of STLSOFT_NUM_ELEMENTS() in the STLSoft libraries, and read about it all in chapter 14 of Imperfect C++.

edit: some of the commenters suggest that the implementation does not reject pointers. It does (as well as user-defined types), as illustrated by the following program. You can verify this by uncommented lines 16 and 18. (I just did this on Mac/GCC4, and it rejects both forms).

1
2 #include <stlsoft/stlsoft.h>
3
4 #include <vector>
5
6 #include <stdio.h>
7
8 int main()
9 {
10         int     ar[1];
11         int*    p = ar;
12         std::vector<int>        v(1);
13
14         printf("ar: %lun", STLSOFT_NUM_ELEMENTS(ar));
15
16 //      printf("p: %lun", STLSOFT_NUM_ELEMENTS(p));
17
18 //      printf("v: %lun", STLSOFT_NUM_ELEMENTS(v));
19
20         return 0;
21 }
22
链接地址: http://www.djcxy.com/p/86714.html

上一篇: 什么是0 [p]在做什么?

下一篇: C ++数组[索引]与索引[数组]