Subscribed unsubscribe Subscribe Subscribe

C配列参照演算子の興味深い仕様

open-std.org のC99 Rationaleを読んでいて、興味深い一節を発見。

6.5.2 Postfix operators 6.5.2.1 Array subscripting
The C89 Committee found no reason to disallow the symmetry that permits a[i] to be written as i[a].

The syntax and semantics of multidimensional arrays follow logically from the definition of arrays and the subscripting operation. The material in the Standard on multidimensional arrays introduces no new language features, but clarifies the C treatment of this important abstract data type.

これ、どこか (2ch だったか v*** 先生だったか忘れたけど) で見た記憶が。要は、

#include <stdio.h>

int main()
{
        int i = 1;
        char c = i["test"];
        printf("%c\n", c);
        return 0;
}

これがエラーなくコンパイルできて、しかも実行するとちゃんと

e

と表示されるという話。C99 から導入された複合リテラルを使えば、もっとキモくなります。

#include <stdio.h>

int main()
{
        int i = 1;
        struct moo {
                int a;
        };

        struct moo m = i[(struct moo[3]){ { 1 }, { 2 }, { 3 } }];
        printf("%d\n", m.a);
        return 0;
}

もう、もはや何語かわかりませんね。ちなみにこの書き方で void * を dereference するとどうなるか、

#include <stdio.h>

int main()
{
        int i = 1;
        void *a = "abc";
        char c = i[a];
        printf("%c\n", c);
        return 0;
}
moriyoshi% gcc -std=c99 -Wall -o test test.c
test.c: In function 'main':
test.c:7: warning: dereferencing 'void *' pointer
test.c:7: error: void value not ignored as it ought to be

と、ちゃんとエラーになるようです。