vectores que programacion nombres imprimir estructuras cadenas arreglos arreglo array almacenar c gcc c99 c11 variable-length-array

nombres - que es un array en programacion



Array de longitud variable en medio de la estructura: por qué este código C es válido para gcc (3)

El estándar es bastante claro que los VLA no están permitidos en una struct :

6.7.2.1 Especificadores de estructura y unión

9 - Un miembro de una estructura o unión puede tener cualquier tipo de objeto completo que no sea un tipo modificado de forma variable. [...]

Los tipos modificados de forma variable son (como podría esperarse) aquellos derivados de una matriz de longitud variable (por ejemplo, agregando dimensiones de matriz o calificadores de CV):

6.7.6 Declaradores

3 - [...] Si, en la secuencia anidada de declaradores en un declarador completo, hay un declarador que especifica un tipo de matriz de longitud variable, se dice que el tipo especificado por el declarador completo se modifica de forma variable. Además, cualquier tipo derivado por la derivación de tipo declarador de un tipo modificado de forma variable se modifica de manera variable.

Hay algún código extraño que usa VLA (Arreglos de longitud variable) que se trata como válido C (C99, C11) por gcc 4.6

$ cat a.c int main(int argc,char**argv) { struct args_t{ int a; int params[argc]; // << Wat? // VLA in the middle of some struct, between other fields int b; } args; args.b=0; for(args.a=0;args.a<argc;args.a++) { args.params[args.a]=argv[0][0]; args.b++; } return args.b; }

Este código compilado sin advertencias:

$ gcc-4.6 -Wall -std=c99 a.c && echo $? 0 $ ./a.out ; echo $? 1 $ ./a.out 2; echo $? 2 $ ./a.out 2 3; echo $? 3

Lo mismo para -std=c1x :

$ gcc-4.6 -Wall -std=c1x a.c && echo $? 0

Pero esto no funciona con Intel C Compiler o con Clang + LLVM:

$ icc a.c -o a.icc a.c(5): warning #1361: variable-length array field type will be treated as zero-length array field type int params[argc]; ^ $ ./a.icc; echo $? 47 $ clang a.c -o a.clang a.c:5:10: error: fields must have a constant size: ''variable length array in structure'' extension will never be supported int params[argc]; ^ 1 error generated.

Asi que:

  1. ¿Por qué esto es considerado válido por GCC?
  2. Si es una extensión de GCC, ¿dónde se describe?
  3. ¿Es válido en las normas ISO C99 y C11?

GCC no lo permite, compilar con -std=c99 -pedantic-errors . Un VLA dentro de una estructura es aparentemente una característica no estándar de GNU C (mal documentada). Ver esto


Los autores del Estándar C89 reconocieron que muchas implementaciones implementaron características útiles que podrían ser poco prácticas en otras implementaciones, y reconocieron eso como algo bueno . La Norma fue pensada como un conjunto mínimo de requisitos para implementaciones; nunca tuvo la intención de desalentar las implementaciones de proporcionar características más allá de eso.

La Norma requiere que si una implementación conforme permite que una matriz de longitud variable se declare dentro de una estructura definida en el ámbito del bloque, debe documentar dicho comportamiento como una extensión o emitir un diagnóstico cuando el código contenga dicha declaración. Dado que una implementación sería libre de procesar el código como quiera después de emitir dicho diagnóstico, ya sea que documente o no una extensión , el requisito de documentar las extensiones solo se puede aplicar de manera significativa a las extensiones que no generan diagnósticos. Eso a su vez sugeriría que tales cosas deben ser permitidas.

El Estándar requiere que las extensiones no afecten de manera adversa el comportamiento de ningún programa de Estricta Conformidad, pero dado que ningún programa de este tipo podría contener una declaración VLA dentro de una estructura, el requisito no es un problema aquí.