Consider the following piece of code.
#include <iostream>
int main(){
int a[] = {1,2,3,4,5};
int b = 5;
std::cout << a[b] << std::endl;
std::cout << b[a] << std::endl;
}
I understand that a[b] and b[a] are identical, as specified by the standard:
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.
However, I still don't quite understand. The compiler does address arithmetic in bytes. Since an int takes up 4 bytes, both a[b] and b[a] are translated into *(a + b * 4). My question is: how does the compiler determine that the correct translation is *(a + b * 4), instead of *(b + a * 4)? When the compiler is given an expression in the form of E1[E2], the compiler can translate it into either *(E1 + E2 * 4), or *(E2 + E1 * 4) - how does the compiler know which one is the correct choice?