Hay un lenguaje extraño (pero útil) en C que se encuentra a menudo. Y puede que te resulte útil aquí.
typedef union {
short int x;
float y;
unsigned char z[1];
} MyUnion;
int main( int argc, char *argv[] ) {
MyUnion s;
s.x = 1000;
printf("%u %u %u\n", sizeof(MyUnion), s.z[0], s.z[1]);
return 0;
}
Tenga en cuenta que ni siquiera necesita especificar la extensión real de z []. Ajustarlo a uno cumple con el estándar moderno de sintaxis. Superar el límite de cualquier matriz en tiempo de ejecución es un comportamiento indefinido, pero por lo tanto usaremos una matriz para indexar a través de cualquier declaración, ya que los problemas de relleno y alineación dependen del objetivo, de todos modos.
El uso de índices fuera del límite dado se encuentra en el código del compilador c, las bibliotecas (malloc, por ejemplo, a menudo usa [-1] como un índice de matriz), sistemas operativos y otros. Es bastante común, por ejemplo, encontrar en el uso de:
typedef struct {
int typecode;
int len;
char s[1];
} packet_t;
para paquetes de red, registros de archivos de objetos, etc. La asignación real se realiza a través de malloc, sin embargo, para garantizar que exista el tamaño adecuado. No está mal y se hace a menudo.
Ya que es parte de una unión, comenzará desde el principio. Pero el tamaño de la unión será determinado por el elemento más grande y no por él.
C requiere que cualquier objeto tenga una dirección única. Entonces, si la unión no tiene otras definiciones dentro de ella, la creación de una instancia del objeto requerirá espacio. Pero esto es simplemente para cumplir con el requisito de que diferentes instancias tengan direcciones diferentes.
Si simplemente estuviera tratando de crear una matriz de bytes que asigne una unión de objeto (s), definitivamente NO me molestaría en absoluto con un operador sizeof (). Simplemente lo escribiría como lo hice arriba. Guarda texto y guarda el riesgo de tener que editar esa línea si cambio el nombre de algo.