December 9th, 2024

Is this the weirdest thing in C?

The article explains C programming's pointer and array indexing peculiarities, highlighting that x[i] and i[x] access the same memory address, despite i[x] being unconventional and discouraged.

Read original articleLink Icon
Is this the weirdest thing in C?

The article discusses some of the peculiarities of the C programming language, particularly focusing on the behavior of pointers and array indexing. It highlights the expression x[i] == i[x], which demonstrates that accessing an array element can be done in two seemingly different ways that yield the same result. This is due to the way arrays are treated in C, where the name of the array acts as a pointer to its first element. The author explains that both x[i] and i[x] access the same memory address, illustrating this with a simple code example. The output confirms that both expressions return the same value, although using i[x] is unconventional and not recommended in practice. The article concludes by acknowledging that while this may not be the weirdest aspect of C, it certainly exemplifies the language's quirks.

- C's array indexing allows for unconventional expressions like x[i] == i[x].

- Both expressions access the same memory address due to the commutative property of addition.

- The article provides a code example to illustrate this behavior.

- Using i[x] is discouraged despite it being functionally equivalent to x[i].

- The discussion highlights the challenges novice programmers face with C's pointer and memory management concepts.

Link Icon 5 comments
By @tromp - about 1 month
This weirdest thing has been a staple of entries in the IOCCC [1]. It is used not only to obfuscate, but also to save characters. For example, in this 1989 arbitrary length maze generator submission

    char*M,A,Z,E=40,J[40],T[40];main(C){for(*J=A=scanf(M="%d",&C);
    --            E;             J[              E]             =T
    [E   ]=  E)   printf("._");  for(;(A-=Z=!Z)  ||  (printf("\n|"
    )    ,   A    =              39              ,C             --
    )    ;   Z    ||    printf   (M   ))M[Z]=Z[A-(E   =A[J-Z])&&!C
    &    A   ==             T[                                  A]
    |6<<27<rand()||!C&!Z?J[T[E]=T[A]]=E,J[T[A]=A-Z]=A,"_.":" |"];}
the Z[A-(E ... :" |"] expression spanning the last 3 lines saves 2 characters over the conventional alternative (A-(E ... :" |")[Z].

[1] https://www.ioccc.org/

By @NoZZz - about 1 month
Of course not, everyone knows that a[b] is equivalent to *(a+b)
By @fargle - about 1 month
"the worst feature of C is that switches don't break automatically before each case label. This code forms some sort of argument in that debate, but I'm not sure whether it's for or against"

https://www.lysator.liu.se/c/duffs-device.html (the original, better description)

https://en.wikipedia.org/wiki/Duff%27s_device

https://xkcd.com/1053/

By @chunkyguy - about 1 month
C has many syntactic sugar and [] operator is one of them. -> is another popular one.