Apa sintaks “[0… 255] =” ini di C?

108

Mengacu pada js0n.c

Sintaks kodenya adalah seperti di bawah ini:

    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;

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

Adakah yang bisa menjelaskan apa yang dilakukan di sini? Apa sintaks [0 ... 255]dan &&l_badlakukan di sini?

Gaurav K
sumber

Jawaban:

109

... adalah ekstensi yang disediakan oleh GCC

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

Untuk menginisialisasi berbagai elemen ke nilai yang sama, tulis [first ... last] = value. Ini adalah ekstensi GNU. Sebagai contoh,

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

&& adalah ekstensi lain

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

Anda bisa mendapatkan alamat label yang ditentukan dalam fungsi saat ini (atau fungsi yang memuat) dengan operator unary &&. Nilainya memiliki tipe void *. Nilai ini adalah konstanta dan dapat digunakan di mana pun jenis konstanta tersebut valid. Sebagai contoh:

 void *ptr;
 /* ... */
 ptr = &&foo;
pengguna657267
sumber
22
menyatukan semuanya kode itu membuat tabel lompat yang menggunakan nilai ascii untuk indeks, mungkin untuk parser.
ratchet freak
1
Secara khusus parser JSON, sejauh yang saya tahu.
Kevin
1
@Kevin itu masuk akal. Kapan itu menjadi kesalahan sintaks untuk menerapkan address-of operator (&) ke rvalue? Saya menebak di C99, mungkin? Terakhir kali saya menggunakan Visual C ++ secara teratur adalah sekitar tahun 1998, yang akan menjadi standar ANSI pra-C99, dan kompiler mengizinkannya kemudian (saya tahu karena saya ingat salah ketik dari &kode produksi yang masuk ke kode produksi!).
dodgethesteamroller
3
@dodgethesteamroller &&adalah token yang sepenuhnya terpisah dari &, jadi tidak mungkin tata bahasa C standar dapat menafsirkan &&xsebagai "alamat alamat x" terlepas dari kategori nilai &x.
Tavian Barnes
4
@dodgethesteamroller: --selalu diurai sebagai --, dan &&selalu diurai sebagai &&. C99 §6.4¶4: token preprocessing berikutnya adalah urutan karakter terpanjang yang dapat membentuk token preprocessing
ninjalj