lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Feb 7, 2018 at 9:00 PM, Sean Conner <sean@conman.org> wrote:
> It was thus said that the Great Paige DePol once stated:
>> >> I don't know what you mean by "the whole 2[pa] bit" though, can you explain?
>> >
>> > #include <stdio.h>
>> >
>> > char *a[] = { "zero" , "one" , "two" , "three" };
>> >
>> > int main(void)
>> > {
>> >  puts( a[0] );
>> >  puts( 1[a] );
>> >
>> >  putchar( 2[ 3[a] ] ); putchar('\n');
>> >  putchar( 2["0123"] ); putchar('\n');
>> >
>> >  return 0;
>> > }
>> >
>> >  Valid.  And it runs without error.
>>
>> What the heck is this voodoo magic? I have never seen this syntax before.
>
>   It comes because array syntax is "syntactic surgar."  So let's take a[1].
> This is
>
>         a[1] = *(a + 1)
>
> And because addition is commutative, you also have
>
>         a[1] = *(1 + a)
>
> which, when you adjust the left side:
>
>         1[a] = *(1 + a)
>
> And viola!  Voodoo magic.
>
>   -spc
>
> [1]     An example, not a real foot note [2].
>
> [2]     If there were real foot notes, there would be foot notes. [3]
>
> [3]     Fnord.

Unfortunately, it's not a stringed instrument[1].

One thing that complicates the a[1] / 1[a] symmetry is that you have
to deal with type coercion:

intptr_t(a + 1) != intptr_t(a) + 1 // unless a is char*

The actual pointer value of the result is intptr_t(a) + 1 * sizeof(*a).

The reason x[y] is commutative is because the + operator, given a
pointer operand, performs a type coercion on the pointer operand. It
IS exactly that substitution, but there's a lot more magic going on
than meets the eye.

Also, it's not FULLY commutative: a[1][2] can be written as 1[a][2],
but 1[a][2] cannot be written as 1[2][a]. There are limits to the
magic.

/s/ Adam

[1] https://en.wikipedia.org/wiki/Viola - I believe you're looking for "voila".