Что это за синтаксис «[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/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;
user657267
источник
22
Собирая все вместе, этот код создает таблицу переходов, которая использует значения ascii для индексов, предположительно для парсера.
храповой урод
1
В частности, парсер JSON, насколько я могу судить.
Кевин
1
@KevinM, в этом есть смысл. Когда применение оператора адресации (&) к rvalue стало синтаксической ошибкой? Я догадываюсь, что в C99? В последний раз я регулярно использовал Visual C ++ примерно в 1998 году, когда это был стандарт ANSI до C99, и тогда компилятор разрешил это (я знаю, потому что помню опечатку с двойным &вводом кода в производственный код!).
dodgethesteamroller
3
@dodgethesteamroller &&- это совершенно отдельный токен &, поэтому стандартная грамматика C не может интерпретировать &&xкак «адрес адреса x» независимо от категории значения &x.
Тавиан Барнс
4
@dodgethesteamroller: --всегда анализируется как --и &&всегда анализируется как &&. C99 §6.4¶4: следующий токен предварительной обработки - это самая длинная последовательность символов, которая может составлять токен предварительной обработки
ninjalj