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?

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;

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.