matrices de longitud cero

Recientemente encontré una definición de estructura

struct arr { int cnt; struct { int size; int *name; } list[0]; }; 

y ahora no sé el motivo de la statement de la list[0] . Lo que me interesa es por qué se usa esto. ¿Tiene alguna ventaja? ¿Y si si, que?

El uso es para matrices de longitud dinámica. Puede asignar la memoria utilizando malloc() y hacer que la matriz resida al final de la estructura:

 struct arr *my_arr = malloc(sizeof *my_arr + 17 * sizeof *my_arr->list); my_arr->cnt = 17; my_arr->list[0].size = 0; my_arr->list[1].name = "foo"; 

En realidad, poder usar 0 para la longitud es (como se señala en un comentario) una extensión GCC. En C99, puede omitir el tamaño literal por completo para el mismo efecto.

Antes de que se implementaran estas cosas, a menudo veía esto hecho con una longitud de 1, pero eso complica un poco la asignación ya que debe compensar al calcular la memoria necesaria.

Se llama “struct hack”. Puede buscarlo en SO o en la red

http://www.google.com/search?q=struct+hack&sitesearch=stackoverflow.com/questions

Tenga en cuenta que formalmente siempre es ilegal declarar matrices de tamaño 0 en C. El código que proporcionó formalmente ni siquiera es comstackble. Sin embargo, la mayoría de los comstackdores de C aceptarán una statement de matriz de 0 como extensión, específicamente porque a menudo se usa en la versión “perezosa” de “struct hack” (puede confiar en sizeof para determinar cuánta memoria asignar, ya que la matriz de 0 tamaños supuestamente no afecta el tamaño total de la estructura).

Una mejor implementación de struct hack utiliza una matriz de tamaño 1

 struct arr { int cnt; struct { int size; int *name; } list[1]; }; 

Es “mejor” porque al menos es formalmente comstackble. Para asignar memoria para una estructura con N elementos en la list , se usa offsetof macro estándar

 arr *a = malloc(offsetof(arr, list) + N * sizeof a->list); 

En la versión C99 de la especificación del lenguaje, el “struct hack” es soportado a través de una statement de matriz sin tamaño (con empty [] ), ya que las declaraciones de matriz de 0-size también son ilegales en C99.

Otra ventaja es si su estructura describe datos en disco / en red. Si cnt es 0, el tamaño de los datos solo puede ser la longitud de cnt .

Estoy aquí solo para confirmar lo que temía, esa list[0] no es válida.