Що це за синтаксис “[0… 255] =” в C?


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/Designized-Inits.html#Designized-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, що має сенс. Коли стала синтаксичною помилкою застосувати адресу оператора (&) до rvalue? Я здогадуюсь у С99, можливо? Востаннє, коли я регулярно використовував Visual C ++, був приблизно в 1998 році, що було б стандартом ANSI до C99, і компілятор це дозволив тоді (я знаю, бо пам’ятаю помилку подвійного &входження у виробничий код!).
dodgethesteamroller

3
@dodgethesteamroller &&- це абсолютно окремий маркер &, тому стандартна граматика C не може інтерпретувати &&xяк "адресу адреси x" незалежно від категорії значень &x.
Тавіан Барнс

4
@dodgethesteamroller: --завжди аналізується як --і &&завжди аналізується як &&. C99 §6.4¶4: наступний маркер попередньої обробки - це найдовша послідовність символів, яка може складати маркер попередньої обробки
ninjalj
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.