Swapping identifiers and subscripts when accessing built-in arrays and initialiser lists for multi-dimensional arrays

StackOverflow https://stackoverflow.com/questions/22892183

Вопрос

I was hoping someone could enlighten me as to the following, seemingly, curious syntax. I would like to understand its potential usefulness or the mechanism that makes the syntax valid.

If you have

char A[] {'a', 'b', 'c'};

then 2[A] == 'c'.

Q1: Is this effect stemming from the parsing rules for expressions that involve access to elements of multi-dimensional built-in arrays? E.g., B[ i ][ j ][ k ].

Q2: What is the rationale behind

int A[][2] {{1, 2}, {3, 4}};

being valid, but

int A[][] {{1, 2}, {3, 4}};

being not? (the error reads Array has incomplete element type 'int[]')

Thanks in advance.

Это было полезно?

Решение

I would like to understand its potential usefulness

It has no use, apart from obfuscation. It's just a quirk of the way [] is defined.

the mechanism that makes the syntax valid

a[b] is defined to be equivalent to *(a+b). Since addition is commutative, this is equivalent to *(b+a), and hence to b[a].

int A[][] {{1, 2}, {3, 4}};

In order to declare an array, the element type must be complete; that is, it must have been fully defined, so that the compiler knows its size. Otherwise, the compiler can't know how the elements are arranged in memory, so can't generate the pointer arithmetic needed to access them. The size of the array itself can be left unspecified, since that's not needed to access the elements.

A multi-dimensional array is an array of arrays, and the same rule applies: while the size of the outer array can be left unspecified, the inner array type must be complete. For an array type to be complete, its size must be specified.

Другие советы

It stems from the fact that A[2] is the same as *(A+2), which in turn is the same as *(2+A). Aside from usage to confuse novice programmers, it serves absolutely no useful purpose. But since there probably is SOME code that relies on this, it can't be removed.

Q1. I don't think so. Note that B[2][3] can be replaced with, something like 3[(B[2])], but no sane person would write that and hope that others would understand it.

Q2. That's just the way the language is defined. The compiler should know the size of all elements except the outermost. It makes writing the compiler easier, because (in theory) the compiler could store away the ready-made content of the array one element at a time. Of course, modern compilers don't necessarily do that, but if you want to write a C or C++ compiler to run on a machine with limited memory, you may wish to do that. It could even be written out to an object file immediately, from that perspective.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top