Cの「[0…255] =」構文とは何ですか?


108

js0n.cを参照する

コードの構文は次のとおりです。

    static void *gostruct[] =
    {
        [0 ... 255] = &&l_bad,
        ['\t'] = &&l_loop, [' '] = &&l_loop, ['\r'] = &&l_loop, ['\n'] = &&l_loop,
        ['"'] = &&l_qup,
        [':'] = &&l_loop, [','] = &&l_loop,
        ['['] = &&l_up, [']'] = &&l_down, // tracking [] and {} individually would allow fuller validation but is really messy
        ['{'] = &&l_up, ['}'] = &&l_down,
        ['-'] = &&l_bare, [48 ... 57] = &&l_bare, // 0-9
        [65 ... 90] = &&l_bare, // A-Z
        [97 ... 122] = &&l_bare // a-z
    };

........
.......

l_bad:
    *vlen = cur - json; // where error'd
    return 0;

........
........

誰かがここで何が行われているのか説明できますか?構文[0 ... 255]&&l_badは何ですか?

回答:


109

... GCCが提供する拡張機能です

https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html#Designated-Inits

要素の範囲を同じ値に初期化するには、を書き込み[first ... last] = valueます。これはGNU拡張機能です。例えば、

 int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };

&& 別の拡張機能です

https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html#Labels-as-Values

単項演算子を使用すると、現在の関数(またはそれを含む関数)で定義されているラベルのアドレスを取得できます&&。値のタイプはvoid *です。この値は定数であり、その型の定数が有効な場合はいつでも使用できます。例えば:

 void *ptr;
 /* ... */
 ptr = &&foo;

22
まとめると、そのコードは、おそらくパーサーのために、インデックスにASCII値を使用するジャンプテーブルを作成しています。
ラチェットフリーク

1
具体的には、私が知る限り、JSONパーサーです。
ケビン

1
意味のある@KevinM。右辺値にアドレス演算子(&)を適用すると構文エラーになったのはいつですか?たぶんC99だと思いますか?最後にVisual C ++を定期的に使用したのは1998年頃で、これはC99より前のANSI規格でしたが、コンパイラーはそれを許可していました(二重に&なって製品コードに入るというタイプミスを覚えているので知っています!)。
dodgethesteamroller

3
@dodgethesteamrollerはと&&は完全に別のトークン&であるため、標準のC文法が&&xの値カテゴリに関係なく「xのアドレスのアドレス」と解釈することはできません&x
Tavian Barnes、2015

4
@dodgethesteamroller:--は常にとして解析され--&&常にとして解析され&&ます。C99§6.4¶4:次の前処理トークンは、前処理トークンを構成する可能性のある最長の文字シーケンスです
ninjalj
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.