Otro uso de la matriz de longitud cero es como una etiqueta con nombre dentro de una estructura para ayudar a compilar la verificación de compensación de la estructura en el tiempo.
Suponga que tiene algunas definiciones de estructuras grandes (abarcan varias líneas de caché) que desea asegurarse de que estén alineadas con el límite de la línea de caché tanto al principio como en el medio donde cruza el límite.
struct example_large_s
{
u32 first; // align to CL
u32 data;
....
u64 *second; // align to second CL after the first one
....
};
En el código, puede declararlos usando extensiones GCC como:
__attribute__((aligned(CACHE_LINE_BYTES)))
Pero aún desea asegurarse de que esto se aplique en tiempo de ejecución.
ASSERT (offsetof (example_large_s, first) == 0);
ASSERT (offsetof (example_large_s, second) == CACHE_LINE_BYTES);
Esto funcionaría para una sola estructura, pero sería difícil cubrir muchas estructuras, cada una tiene un nombre de miembro diferente para alinear. Lo más probable es que obtenga un código como el siguiente, donde tiene que encontrar los nombres del primer miembro de cada estructura:
assert (offsetof (one_struct, <name_of_first_member>) == 0);
assert (offsetof (one_struct, <name_of_second_member>) == CACHE_LINE_BYTES);
assert (offsetof (another_struct, <name_of_first_member>) == 0);
assert (offsetof (another_struct, <name_of_second_member>) == CACHE_LINE_BYTES);
En lugar de ir de esta manera, puede declarar una matriz de longitud cero en la estructura que actúa como una etiqueta con nombre con un nombre coherente pero no consume ningún espacio.
#define CACHE_LINE_ALIGN_MARK(mark) u8 mark[0] __attribute__((aligned(CACHE_LINE_BYTES)))
struct example_large_s
{
CACHE_LINE_ALIGN_MARK (cacheline0);
u32 first; // align to CL
u32 data;
....
CACHE_LINE_ALIGN_MARK (cacheline1);
u64 *second; // align to second CL after the first one
....
};
Entonces el código de aserción en tiempo de ejecución sería mucho más fácil de mantener:
assert (offsetof (one_struct, cacheline0) == 0);
assert (offsetof (one_struct, cacheline1) == CACHE_LINE_BYTES);
assert (offsetof (another_struct, cacheline0) == 0);
assert (offsetof (another_struct, cacheline1) == CACHE_LINE_BYTES);