En el lenguaje C, las estructuras (struct) pueden incluir otras estructuras y diferentes tipos de datos. Sin embargo, la disposición de los campos dentro de la estructura puede afectar su tamaño y alineación. El compilador añade bytes adicionales (padding) para cumplir con la alineación (alignment) del campo más grande. Esto es importante para el rendimiento y el funcionamiento adecuado del procesador.
Si una estructura contiene estructuras anidadas, el alineamiento se aplica de manera recursiva:
#pragma pack en MSVC o el atributo __attribute__((packed)) en GCC/Clang).Ejemplo:
#include <stdio.h> struct Inner { char c; int x; }; struct Outer { char a; struct Inner b; short s; }; int main() { printf("sizeof(struct Inner) = %zu ", sizeof(struct Inner)); printf("sizeof(struct Outer) = %zu ", sizeof(struct Outer)); return 0; } // sizeof(struct Inner) = 8 (en 64-bit), sizeof(struct Outer) = 16 o 24
El uso de pack y packed reduce el tamaño al ignorar la alineación, pero esto puede disminuir el rendimiento o causar errores en algunas plataformas (ARM, DSP, etc.).
Pregunta: ¿Se puede garantizar que una misma estructura tenga el mismo tamaño en todas las plataformas?
Respuesta: ¡No! El estándar C no garantiza la misma alineación, el orden de bytes (endian), y puede "añadir" padding entre campos y al final de la estructura. Para la compatibilidad binaria de las estructuras, utiliza un control manual de la alineación y siempre prueba explícitamente sizeof en cada plataforma de destino.
Ejemplo:
struct Data { char c; int x; }; // sizeof(Data) normalmente 8 en 64-bit, 5 o 8 en 32-bit
Historia
Al intercambiar una estructura entre un microcontrolador (ARM) y una PC a través de un protocolo binario, los datos recibidos de ARM no coincidían con lo esperado en la PC — debido a diferentes padding y orden de bytes. Esto causó que se decodificaran incorrectamente los parámetros, lo que llevó a errores físicos en el control del dispositivo.
Historia
En un protocolo de red, para acelerar el envío de datos se añadieron estructuras packed, pero no se tuvo en cuenta que en una plataforma sin alineación, algunos campos no funcionaban (el procesador no soportaba acceso desalineado). Resultado: excepciones de hardware al trabajar con paquetes de red.
Historia
Un servidor trabajaba con un archivo externo compuesto de registros de estructura. Después de actualizar el compilador, el tamaño de la estructura cambió (diferente alineación). Los datos antiguos en el archivo dejaron de leerse correctamente, y parte de la información se volvió "corrupta".