Declarar vector de tamaño cero

¿Qué significa lo siguiente?

struct foo { ... char bar[0]; // Zero size??? }; 

Le pregunté a mis colegas y me dijeron que es lo mismo que escribir void* bar .

Por lo que sé, un puntero C es solo una variable de 4 bytes (al menos en una máquina de 32 bits). ¿Cómo puede saber el comstackdor que la barra [0] es un puntero (y por lo tanto tiene una longitud de 4 bytes)? ¿Eso es solo azúcar sintáctica?

Sus colegas mintieron. (Probablemente no intencionalmente, así que no te enojes con ellos ni nada).

Esto se denomina miembro de matriz flexible, y en C99 se escribe como char bar[]; , y en C89 fue escrito como char bar[1]; , y que algunos comstackdores le permitirían escribir como char bar[0]; . Básicamente, solo usas punteros a la estructura y los asignas con una cantidad de espacio adicional al final:

 const size_t i = sizeof("Hello, world!"); struct foo *p = malloc(offsetof(struct foo, bar) + i); memcpy(p->bar, "Hello, world!", i); // initialize other members of p printf("%s\n", p->bar); 

De esa manera, p->bar almacena una cadena cuyo tamaño no está limitado por una statement de matriz, pero que todavía se realiza en la misma asignación que el rest de la struct (en lugar de necesitar que el miembro sea un char * y necesite Dos malloc s y dos s free para configurarlo.

La respuesta de Chris es correcta, pero probablemente asignaría el objeto de forma ligeramente diferente.

 int n = ...; // number of elements you want struct foo *p = malloc(offsetof(struct foo, bar[n])); 

luego iterar sobre ello con

 for (int i = 0; i < n; ++i) { p->bar[i] = ...; } 

El punto clave es que la respuesta de Chris funciona desde sizeof(char)==1 , pero para otro tipo, tendría que multiplicar explícitamente por sizeof *bar .

¡Esto debería ser un error de comstackción! Solo las matrices asignadas dinámicamente se pueden asignar con 0 de tamaño.

También se accederá a una matriz mediante punteros (los índices son punteros implícitos). Así que sospecho, si te lo dicen, esto será interpretado como un puntero. Como es una matriz de longitud cero, probablemente apunte al siguiente valor (¿espero que algo siga en esa estructura?).

Esto es suspensión, no conocimiento. 🙂

Sin embargo, no es como harías cualquier cosa … Si quieren un puntero, deberían usar un puntero. Si no pueden decirte por qué está ahí, no debería estarlo.