¿Cuál es esta sintaxis “[0… 255] =” en C?

108

Haciendo referencia a js0n.c

La sintaxis del código es la siguiente:

    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;

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

¿Alguien puede explicar qué se está haciendo aquí? ¿Qué hace la sintaxis [0 ... 255]y &&l_badaquí?

Gaurav K
fuente

Respuestas:

109

... es una extensión proporcionada por GCC

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

Para inicializar un rango de elementos con el mismo valor, escriba [first ... last] = value. Esta es una extensión GNU. Por ejemplo,

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

&& es otra extensión

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

Puede obtener la dirección de una etiqueta definida en la función actual (o una función contenedora) con el operador unario &&. El valor tiene tipo void *. Este valor es una constante y se puede utilizar siempre que sea válida una constante de ese tipo. Por ejemplo:

 void *ptr;
 /* ... */
 ptr = &&foo;
usuario657267
fuente
22
Al poner todo junto, ese código está creando una tabla de salto que usa valores ascii para índices, presumiblemente para un analizador.
fanático del trinquete
1
Específicamente un analizador JSON, por lo que puedo decir.
Kevin
1
@KevinM eso tiene sentido. ¿Cuándo se convirtió en un error de sintaxis aplicar el operador de dirección de (&) a un rvalue? Supongo que en C99, ¿quizás? La última vez que usé Visual C ++ con regularidad fue alrededor de 1998, que habría sido el estándar ANSI anterior a C99, y el compilador lo permitió entonces (lo sé porque recuerdo un error tipográfico de un duplicado al &ingresar al código de producción).
dodgethesteamroller
3
@dodgethesteamroller &&es un token completamente separado de &, por lo que no hay forma de que la gramática C estándar pueda interpretarse &&xcomo "dirección de la dirección de x" independientemente de la categoría de valor de &x.
Tavian Barnes
4
@dodgethesteamroller: --siempre se analiza como --y &&siempre se analiza como &&. C99 §6.4¶4: el siguiente token de preprocesamiento es la secuencia más larga de caracteres que podría constituir un token de preprocesamiento
ninjalj