para - ¿Cuál es el propósito de una matriz de longitud cero en una estructura?
poligono en r (2)
Esta pregunta ya tiene una respuesta aquí:
Cuando estoy buscando el código del kernel de Linux, encontré el siguiente código:
struct thread_info {
struct task_struct *task;
struct exec_domain *exec_domain;
unsigned long flags;
__u32 status;
__u32 cpu;
int preempt_count;
mm_segment_t addr_limit;
struct restart_block restart_block;
void __user *sysenter_return;
unsigned long previous_esp;
__u8 supervisor_stack[0];
};
Tenga en cuenta que la última variable "supervisor_stack", es una matriz de longitud cero, ¿cuál es su uso? ¡Gracias por adelantado!
Es la versión anterior a C99 de un miembro de matriz flexible, ofrecido por GCC como una extensión.
La forma C99 es definir el miembro de la matriz flexible con corchetes vacíos,
__u8 supervisor_stack[];
Se utiliza para almacenar datos cuya cantidad no es constante contigua a la estructura. La memoria se asigna en el formulario.
struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed);
En el párrafo 18 de 6.7.2.1, la norma (borrador N1570) los describe:
Como un caso especial, el último elemento de una estructura con más de un miembro nombrado puede tener un tipo de matriz incompleta; Esto se llama un miembro de matriz flexible. En la mayoría de las situaciones, el miembro de la matriz flexible se ignora. En particular, el tamaño de la estructura es como si se hubiera omitido el miembro de la matriz flexible, excepto que puede tener más relleno posterior del que implicaría la omisión. Sin embargo, cuando un
.
(o->
) el operador tiene un operando izquierdo que es (un puntero a) una estructura con un miembro de matriz flexible y el operando derecho nombra a ese miembro, se comporta como si ese miembro hubiera sido reemplazado por la matriz más larga (con el mismo tipo de elemento ) que no haría la estructura más grande que el objeto al que se accede; el desplazamiento de la matriz seguirá siendo el del miembro de la matriz flexible, incluso si fuera diferente de la matriz de reemplazo. Si esta matriz no tuviera elementos, se comporta como si tuviera un elemento, pero el comportamiento no está definido si se intenta acceder a ese elemento o generar un puntero que lo supera.
Es un pirateo de C común para declarar lo que se puede llamar una matriz de longitud variable (donde se define el tamaño en el momento de la asignación
Ejemplo:
struct line {
int length;
char contents[0];
};
struct line *thisline = (struct line *)
malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
De esta manera, tiene una definición de estructura de sus datos, que también almacena la longitud de la matriz por razones obvias de conveniencia, pero no está limitado por el tamaño fijo que generalmente se asocia con una estructura
Ejemplo tomado de gcc.gnu.org/onlinedocs/gcc/Zero-Length.html (también hay más información allí)