una - sizeof c man
Mecanismo interno de sizeof en C? (4)
A partir de C99, se puede omitir el tamaño de una matriz al final de una estructura. Para propósitos de sizeof(struct)
esta matriz parecerá tener tamaño cero (aunque su presencia puede agregar algo de relleno a la estructura), pero la intención es que su longitud sea flexible , es decir, cuando se debe asignar espacio para la estructura uno la cantidad deseada de espacio extra para la matriz al final. (Para evitar salirse de los límites, la longitud asignada real del conjunto debe almacenarse en algún lugar).
Antes de C99 era un truco bastante común tener una matriz de tamaño 1 (o 0 cuando el compilador lo permitía) al final de una estructura y luego asignarle más espacio, por lo que C99 hizo esta práctica explícitamente permitida al introducir la matriz flexible miembro sin tamaño dado.
Uso sizeof para obtener el tamaño de una estructura en C, pero el resultado que obtuve es inesperado.
struct sdshdr {
int len;
int free;
char buf[];
};
int main(){
printf("struct len:%d/n",(sizeof(struct sdshdr)));
return 0;
} //struct len:8, with or without buf
Mi pregunta es ¿por qué buf
no ocupa ningún espacio y por qué el tamaño del tipo int
sigue siendo 4 en una CPU de 64 bits?
aquí está el resultado de gcc -v
:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.4.0
Thread model: posix
Como una extensión GNU c, tiene matrices de longitud cero:
Como una extensión de GNU, la cantidad de elementos puede ser tan pequeña como cero. Las matrices de longitud cero son útiles como el último elemento de una estructura que realmente es un encabezado para un objeto de longitud variable:
por ejemplo, considere este código del manual de gnu c
struct line
{
int length;
char contents[0];
};
{
struct line *this_line = (struct line *)
malloc (sizeof (struct line) + this_length);
this_line -> length = this_length;
}
En ISO C99, usaría un miembro de matriz flexible, que es ligeramente diferente en sintaxis y semántica:
Los miembros flexibles de la matriz se escriben como contenidos [] sin el 0.
Los miembros flexibles de la matriz tienen un tipo incompleto, por lo que no se puede aplicar el tamaño del operador. Como una peculiaridad de la implementación original de las matrices de longitud cero, sizeof se evalúa como cero.
Los miembros flexibles de la matriz solo pueden aparecer como el último miembro de una estructura que, de lo contrario, no está vacía.
Una estructura que contiene un miembro de matriz flexible, o una unión que contiene dicha estructura (posiblemente recursivamente), puede no ser un miembro de una estructura o un elemento de una matriz. (Sin embargo, estos usos están permitidos por GCC como extensiones).
El [] es un miembro de matriz flexible . No cuentan para el tamaño total de la estructura, porque el estándar C lo dice explícitamente:
6.7.2.1/18
Como un caso especial, el último elemento de una estructura con más de un miembro nombrado puede tener un tipo de matriz incompleto; esto se llama un miembro de matriz flexible. En la mayoría de las situaciones, el miembro de matriz flexible se ignora. En particular, el tamaño de la estructura es como si se hubiera omitido el miembro flexible de la matriz, excepto que puede tener más relleno posterior de lo que implicaría la omisión.
Esto es intencional por diseño, porque el propósito de un miembro de matriz flexible es permitirle asignar datos finales dinámicamente después de la estructura. (Cuando la estructura es un encabezado de archivo, encabezado de protocolo, etc.)
Example incluye discusión sobre extensiones gcc no estándar y el antiguo "struct hack" anterior a C99.
buf
aquí es un flexible array member
flexible Los miembros de matriz flexible tienen un tipo incompleto, por lo que el operador de sizeof no se puede aplicar mientras que la implementación original de zero-length arrays
, sizeof evaluates to zero
.