Os atributos podem ser especificados com dois underscores __ antes e depois de cada palavra. O atributo que irei falar aqui é o packed, ou __packed__.
The packed attribute specifies that a variable or structure field should have the smallest possible alignment--one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.
(GCC 3.3.3 Manual)
Em tradução livre: O atributo packed especifica que uma variável ou campo de uma estrutura deve ter o mínimo de alinhamento possível -- um byte para uma variável, e um bit para um campo, a não ser que você especifique um valor maior que o atributo alinhado.
Isso significa que o GCC não vai adicionar zeros para preencher (para o alinhamento da memória), de modo que as variáveis ou campos fiquem imediatamente ao lado de cada uma. Por exemplo,
struct abc {
int a;
char b;
int c;
};
struct abc teste = {10, 20, 30};
Compilando o programa com a opção -S (compila o programa, mas não faz a montagem nem o link).
gcc -S -c sempacked.c -o sempacked.s
Olhando o arquivo gerado, sempacked.s:
.file "sempacked.c"
.globl test
.data
.align 4
.type teste, @object
.size teste, 12
teste:
.long 10
.byte 20
.zero 3
.long 30
.ident "GCC: (Gentoo 4.4.4-r2 p1.4, pie-0.4.5) 4.4.4"
.section .note.GNU-stack,"",@progbits
Veja o código em negrito. É aonde uma variável teste da estrutura é declarada. Atribuindo valores, para o campo "a" (int) como .long 10 seguido de "b" (char) como .byte 20. Para manter os campos alinhados, veja que o GCC adicionou 3 bytes com valor zero (.zero 3) antes do campo "c" (int), que foi declarado com .long 30. Isso faz com que a estrutura tenha tamanho 12 ao invés de 9, como é esperado.
struct abc {
int a;
char b;
int c;
} __attribute__((__packed__));
struct abc teste = {10, 20, 30};
E ele compilado:
.file "packed.c"
.globl teste
.data
.type teste, @object
.size teste, 9
teste:
.long 10
.byte 20
.long 30
.ident "GCC: (Gentoo 4.4.4-r2 p1.4, pie-0.4.5) 4.4.4"
.section .note.GNU-stack,"",@progbits
Agora ele não gerou o preenchimento de zeros, fazendo com que o tamanho da estrutura abc seja 9. Lembre-se que alinhamento de memória sempre é bom, mesmo que comprometa espaço, então pense duas vezes antes de usar esse atributo. Geralmente, ele é útil quando você quer atribuir a estrutura para um bloco de memória e manipular ele através dos campos da estrutura.