very unclear how this code works

int a[] = {4, 5, 2, 3, 1}; int i = *a; for (;i;) { std::cout << i--[a]; // не понятная строчка } // output: 1325 

what does the decrement apply to ???

well, obviously, to the variable i , since the loop ends.

But how then do appeals to array elements occur? why there is no compilation error?

For the first time in my life I meet a similar code.

    2 answers 2

    The decrement here is applied i at least simply because it can no longer be applied to anything in this record - to its right there is a token [ , which cannot be the beginning of an operand expression.

    The topic of equivalence a[i] and i[a] is utterly crowded. The expression x[y] by definition, only an abbreviated notation for *(x + y) . One operand must be an array / pointer and the other must be an integer or enum value. Moreover, there are no restrictions on the order in which the operands are specified. Therefore, your i--[a] equivalent to *(i-- + a) equivalent to *(a + i--) and is equivalent to a[i--] . There is no "compilation error" here.

    The foregoing applies specifically to the built-in operator [] . For the overloaded operator [] order of the arguments is fixed, that is, for the expression x[y] , only the overloaded version x.operator[](y) will be considered, but not y.operator[](x) .

    • Well, ok it became clearer, I just rarely use in my practice such perverted ways of accessing the elements of an array - ampawd
    • four
      @ampawd: You don’t need to use them. Write like a human being - an array outside, an index inside. It can be assumed that some generic technique can be tied to the ability to swap operands (something seems to be spinning on the edge of memory), but even there it is hardly critical. - AnT
    • Is there a difference in the order of calculation (for the case, if a and i are expressions with side effects)? - VladD
    • @VladD: There is no sequencing (sequencing) between the computations of the operands of the built-in operator [] , i.e. everything is literally equivalent to *(... + ...) option. Those. no difference. - AnT

    The index operator belongs to the class of postfix operators. It is defined as follows (C ++ Standard, Section 5.2.1 Subscripting)

    1 A post fi x expression in square brackets is a post fi x expression.

    That is, the postfix expression is followed by an expression in square brackets.

    In this expression

     i--[a] 

    i-- is a post-decrement operator, which belongs to the class of postfix expressions. So, there is

      i-- [a] | | постфиксное выражение выражение в квадратных скобках 

    So from the point of view of syntax, this expression is absolutely correct.

    Further in the same citation from the standard there is a continuation

    1 ... one of the expressions of the “or of the pointer and the number of expressions” The “T.” The type “T.” has been completely de fi ned object type.64 The expression E1 [E2] is identical to * ((E1) + (E2))

    from which it follows that one of the expressions must be either an array or a pointer, and the other expression is an enumeration or an integer type. Which of these two expressions which type should have no significance, since by definition the expression E1[E2] equivalent to the expression *((E1) + (E2)) .

    In C ++, you can write an even more elaborate construct by adding a plus sign in front of the array name. For example,

     #include <iostream> int main() { int a[] = { 0, 2, 4, 6, 8 }; int i = 0; std::cout << i++[+a] << std::endl; return 0; } 

    In C, such a construction i++[+a] will not be compiled, since in C, unlike C ++, you cannot use unary plus to the array name.

    In C ++, the user can also overload the index operator for the initialization list in curly braces. For example,

     #include <iostream> #include <initializer_list> #include <numeric> int main() { struct A { long long int operator []( std::initializer_list<int> l ) const { return std::accumulate( l.begin(), l.end(), 0ll ); } }; std::cout << A()[{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }] << std::endl; return 0; } 

    Output of the program to the console

     55 
    • and what gives a unary plus in front of the array name? what is the semantic meaning? - ampawd
    • Ie the second sizeof will display the size of the int . Do you want to say? - ampawd
    • @ampawd The second sizeof will display the size of the pointer. - Vlad from Moscow