O que é essa sintaxe “[0… 255] =” em C?

108

Referindo-se a js0n.c

A sintaxe do código é a seguinte:

    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;

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

Alguém pode explicar o que está sendo feito aqui? O que a sintaxe [0 ... 255]e &&l_badfaz aqui?

Gaurav K
fonte

Respostas:

109

... é uma extensão fornecida pelo GCC

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

Para inicializar uma série de elementos com o mesmo valor, escreva [first ... last] = value. Esta é uma extensão GNU. Por exemplo,

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

&& é outra extensão

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

Você pode obter o endereço de um rótulo definido na função atual (ou uma função de conteúdo) com o operador unário &&. O valor tem tipo void *. Esse valor é uma constante e pode ser usado sempre que uma constante desse tipo for válida. Por exemplo:

 void *ptr;
 /* ... */
 ptr = &&foo;
user657267
fonte
22
juntando tudo isso, o código está criando uma tabela de salto que usa valores ascii para índices, presumivelmente para um analisador.
Ratchet freak
1
Especificamente um analisador JSON, pelo que posso dizer.
Kevin
1
@KevinM isso faz sentido. Quando se tornou um erro de sintaxe aplicar o operador de endereço (&) a um rvalue? Estou supondo em C99, talvez? A última vez que usei o Visual C ++ regularmente foi por volta de 1998, que teria sido o padrão ANSI pré-C99, e o compilador permitiu isso então (eu sei porque me lembro de um erro de digitação de um &código dobrado entrando em produção!).
dodgethesteamroller
3
@dodgethesteamroller &&é um token totalmente separado de &, portanto, não há como a gramática C padrão interpretar &&xcomo "endereço de endereço de x", independentemente da categoria de valor de &x.
Tavian Barnes
4
@dodgethesteamroller: --é sempre analisado como --e &&sempre é analisado como &&. C99 §6.4¶4: o próximo token de pré-processamento é a mais longa sequência de caracteres que poderia constituir um token de pré-processamento
ninjalj