Home

The Weird Valid Syntax in C: Why 3[s] Is the Same as s[3]

If you spend enough time looking through C codebases or playing around with obfuscated C contests, you will eventually encounter a bizarre syntax quirk: writing array indexing upside down.

Most programmers are used to arr[i]. But in C, i[arr] is not only syntactically valid — it does the exact same thing, including allowing writes to memory.

Here is a short C program that demonstrates it in action:

#include <stdio.h>

int main(void) {
    char s[] = "WGabc";                 /* writable stack array — both gates open */
    printf("s[3] = %c\n", s[3]);        /* the normal way   */
    printf("3[s] = %c\n", 3[s]);        /* the "backwards" way — same address */
    3[s] = 'X';                         /* WRITE through the backwards index */
    printf("s    = %s\n", s);
    return 0;
}

If you compile and run this code, you get the following output:

s[3] = b
3[s] = b
s    = WGaXc

At first glance, 3[s] = 'X' looks like a compiler bug or invalid syntax. Why does a number subscripted by an array variable even compile, let alone mutate memory?

The Proof: Commutativity Under the Hood

The reason 3[s] works isn’t a hack — it is a direct mathematical consequence of how the C standard defines the subscript operator [].

In C, array indexing is pure syntactic sugar for pointer arithmetic and dereferencing:

a[i]  ≡  *(a + i)

When you trace the equivalence step-by-step, the load-bearing link becomes obvious:

str[0]   ≡  *(str + 0)     ← standard C rule: a[i] ≡ *(a + i)
*(str+0) ≡  *str           ← +0 is identity
*str     ≡  *(0 + str)     ← addition COMMUTES: (str + 0) == (0 + str)
*(0+str) ≡  0[str]         ← standard C rule applied "backwards"

The backwards notation is the party trick; addition commutativity is the core concept.

Because addition in C pointer arithmetic is commutative, *(s + 3) and *(3 + s) evaluate to the exact same memory address. Since a[i] is defined directly as *(a + i), the compiler treats s[3] and 3[s] as completely identical operations.

Takeaway

While you definitely shouldn’t write 3[s] in production code unless you want to confuse your team during a code review, understanding why it works reinforces a fundamental truth about C: arrays decay to pointers, and subscripts are just pointer arithmetic in disguise.

Tags: CArrayPointers