Qual é o significado de "__atributo __ ((empacotado, alinhado (4)))"

122

É a linguagem C. Está escrito que:

typedef struct __attribute__((packed, aligned(4))) Ball {
    float2 delta;
    float2 position;
    //float3 color;
    float size;
    //int arcID;
    //float arcStr;
} Ball_t;
Ball_t *balls;

Diga-me qual é o significado e como usar essa palavra-chave.

Aaron Lee
fonte
4
É um "atributo do tipo" .. (eu achei isto com "atributo C embalado" em Google Certamente outros podem pelo menos fazer tão bom.!)
1
Veja esta pergunta - embora aligned(4)você provavelmente não tenha muito com que se preocupar.
Keith Thompson

Respostas:

157

Antes de responder, gostaria de fornecer alguns dados do Wiki


O alinhamento da estrutura de dados é a maneira como os dados são organizados e acessados ​​na memória do computador. Consiste em duas questões separadas, mas relacionadas: alinhamento de dados e preenchimento da estrutura de dados .

Quando um computador moderno lê ou grava em um endereço de memória, ele faz isso em blocos do tamanho de palavras (por exemplo, blocos de 4 bytes em um sistema de 32 bits). Alinhamento de dados significa colocar os dados em um deslocamento de memória igual a alguns múltiplos do tamanho da palavra, o que aumenta o desempenho do sistema devido à maneira como a CPU lida com a memória.

Para alinhar os dados, pode ser necessário inserir alguns bytes sem sentido entre o final da última estrutura de dados e o início da próxima, que é o preenchimento da estrutura de dados .


O gcc fornece funcionalidade para desativar o preenchimento da estrutura. ou seja, para evitar esses bytes sem sentido em alguns casos. Considere a seguinte estrutura:

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}sSampleStruct;

sizeof(sSampleStruct)será 12 em vez de 8. Por causa do preenchimento da estrutura. Por padrão, no X86, as estruturas serão preenchidas com alinhamento de 4 bytes:

typedef struct
{
     char Data1;
     //3-Bytes Added here.
     int Data2;
     unsigned short Data3;
     char Data4;
     //1-byte Added here.

}sSampleStruct;

Podemos __attribute__((packed, aligned(X)))insistir no preenchimento de tamanho (X) específico. X deve ter poderes de dois. Consulte aqui

typedef struct
{
     char Data1;
     int Data2;
     unsigned short Data3;
     char Data4;

}__attribute__((packed, aligned(1))) sSampleStruct;  

portanto, o atributo gcc especificado acima não permite o preenchimento da estrutura. então o tamanho será 8 bytes.

Se você deseja fazer o mesmo para todas as estruturas, basta pressionar o valor do alinhamento para empilhar usando #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)
Jeyaram
fonte
6
Se a memória armazena dados em pedaços de 4 bytes, por que não adicionar 2 bytes de preenchimento ao curto não assinado (seu comprimento de 2 bytes)? ou compilador basta adicionar bytes de preenchimento ao primeiro e último membros da estrutura? você pode esclarecer isso?
Utilizador
5
@User Plz consulte isso também. Se você ainda não está claro, plz vir para a ajuda stackoverflow.com/questions/11772553/...
Jeyaram
Quem disse que esses bytes de preenchimento são sem sentido não sabe que o acesso a dados desalinhados é uma singularidade da arquitetura x86. Esses bytes são necessários para evitar exceções quando o processador tenta carregar - digamos um número inteiro - dados que ultrapassem seu limite de alinhamento natural.
Tanveer Badar
86
  • packedsignifica que ele usará o menor espaço possível para struct Ball- isto é, amontoará os campos juntos sem preenchimento
  • alignedsignifica que cada struct Ballum começará em um limite de 4 bytes - ou seja, para qualquer struct Ball, seu endereço pode ser dividido por 4

Essas são extensões do GCC, que não fazem parte de nenhum padrão C.

cnicutar
fonte
17

O atributo packedsignifica que o compilador não adicionará preenchimento entre os campos struct. O preenchimento é geralmente usado para tornar os campos alinhados ao tamanho natural, porque algumas arquiteturas impõem penalidades pelo acesso não alinhado ou não o permitem.

aligned(4) significa que a estrutura deve estar alinhada a um endereço divisível por 4.

Julian Stecklina
fonte