Co to za składnia „[0… 255] =” w C?

108

Odnosić się do Odnosząc się js0n.c

Składnia kodu jest następująca:

    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;

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

Czy ktoś może wyjaśnić, co się tutaj dzieje? Co tu robi składnia [0 ... 255]i co &&l_badrobi?

Gaurav K.
źródło

Odpowiedzi:

109

... jest rozszerzeniem udostępnianym przez GCC

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

Aby zainicjować zakres elementów do tej samej wartości, napisz [first ... last] = value. To jest rozszerzenie GNU. Na przykład,

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

&& to kolejne rozszerzenie

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

Możesz uzyskać adres etykiety zdefiniowanej w bieżącej funkcji (lub funkcji zawierającej) za pomocą operatora jednoargumentowego &&. Wartość ma typ void *. Ta wartość jest stała i może być używana wszędzie tam, gdzie ważna jest stała tego typu. Na przykład:

 void *ptr;
 /* ... */
 ptr = &&foo;
user657267
źródło
22
składając to wszystko razem, kod tworzy tablicę skoków, która używa wartości ascii dla indeksów, prawdopodobnie dla parsera.
grzechotka freak
1
W szczególności parser JSON, o ile wiem.
Kevin
1
@KevinM to ma sens. Kiedy zastosowanie operatora address-of (&) do wartości r stało się błędem składniowym? Zgaduję, że w C99, może? Ostatni raz regularnie używałem Visual C ++ około 1998 r., Który byłby standardem ANSI sprzed C99, a kompilator wtedy na to pozwolił (wiem, bo pamiętam literówkę z podwojonym &wejściem do kodu produkcyjnego!).
dodgethesteamroller
3
@dodgethesteamroller &&jest całkowicie oddzielnym tokenem &, więc nie ma możliwości, aby standardowa gramatyka języka C mogła zinterpretować &&xjako „adres adresu x” niezależnie od kategorii wartości &x.
Tavian Barnes
4
@dodgethesteamroller: -- jest zawsze analizowany jako --i &&zawsze przetwarzany jako &&. C99 §6.4¶4: następny token przetwarzania wstępnego to najdłuższa sekwencja znaków, która może stanowić token przetwarzania wstępnego
ninjalj