Outro uso da matriz de comprimento zero é como um rótulo nomeado dentro de uma estrutura para auxiliar na verificação do deslocamento da estrutura do tempo de compilação.
Suponha que você tenha algumas definições grandes de estrutura (que abrangem várias linhas de cache) que deseja garantir que elas estejam alinhadas ao cache da fronteira da linha, tanto no começo quanto no meio em que ela cruza a fronteira.
struct example_large_s
{
u32 first; // align to CL
u32 data;
....
u64 *second; // align to second CL after the first one
....
};
No código, você pode declará-las usando extensões do GCC, como:
__attribute__((aligned(CACHE_LINE_BYTES)))
Mas você ainda deseja garantir que isso seja imposto em tempo de execução.
ASSERT (offsetof (example_large_s, first) == 0);
ASSERT (offsetof (example_large_s, second) == CACHE_LINE_BYTES);
Isso funcionaria para uma única estrutura, mas seria difícil cobrir muitas estruturas, cada uma com um nome de membro diferente a ser alinhado. Você provavelmente obteria código como abaixo, onde você precisa encontrar os nomes do primeiro membro de cada estrutura:
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);
Em vez de seguir esse caminho, você pode declarar uma matriz de comprimento zero na estrutura, atuando como um rótulo nomeado com um nome consistente, mas não consome nenhum espaço.
#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
....
};
Então, o código de asserção de tempo de execução seria muito mais fácil de manter:
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);