Jakie jest znaczenie „__attribute __ ((zapakowane, wyrównane (4)))”


122

Jest to język C. Napisano, że:

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

Proszę, powiedz mi, jakie jest jego znaczenie i jak używać tego słowa kluczowego.


4
To „atrybut typu” … (znalazłem to z „C atrybutem spakowanym” w Google. Z pewnością inni mogą zrobić przynajmniej równie dobrze!)

1
Zobacz to pytanie - chociaż aligned(4)prawdopodobnie nie masz się czym martwić.
Keith Thompson

Odpowiedzi:


157

Zanim odpowiem, chciałbym podać kilka danych z Wiki


Wyrównanie struktury danych to sposób organizowania danych i uzyskiwania do nich dostępu w pamięci komputera. Składa się z dwóch oddzielnych, ale powiązanych zagadnień: wyrównania danych i wypełnienia struktury danych .

Kiedy nowoczesny komputer czyta lub zapisuje na adres pamięci, robi to w fragmentach wielkości słowa (np. 4-bajtowe fragmenty w systemie 32-bitowym). Dopasowanie danych oznacza umieszczenie danych w przesunięciu pamięci równym pewnej wielokrotności rozmiaru słowa, co zwiększa wydajność systemu ze względu na sposób, w jaki procesor obsługuje pamięć.

Aby wyrównać dane, może być konieczne wstawienie kilku bezsensownych bajtów między końcem ostatniej struktury danych a początkiem następnej, czyli wypełnienia struktury danych .


gcc zapewnia funkcję wyłączania dopełniania struktury. tj. aby w niektórych przypadkach uniknąć tych bezsensownych bajtów. Rozważ następującą strukturę:

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

}sSampleStruct;

sizeof(sSampleStruct)będzie 12 zamiast 8. Z powodu wypełnienia struktury. Domyślnie w X86 struktury będą dopełniane do 4-bajtowego wyrównania:

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

}sSampleStruct;

Możemy użyć, __attribute__((packed, aligned(X)))aby nalegać na wypełnienie o określonym rozmiarze (X). X powinno być potęgą dwójki. Zobacz tutaj

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

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

więc wyżej określony atrybut gcc nie pozwala na wypełnienie struktury. więc rozmiar będzie wynosił 8 bajtów.

Jeśli chcesz zrobić to samo dla wszystkich struktur, po prostu możemy przesunąć wartość wyrównania do stosu za pomocą #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)

6
Jeśli pamięć przechowuje dane w 4-bajtowych fragmentach, dlaczego nie dodaje 2 bajtów wypełniających do skrótu bez znaku (jego długości 2 bajty)? czy kompilator po prostu dodaje bajty wypełniające do pierwszego i ostatniego elementu struktury? czy możesz to wyjaśnić.
Użytkownik

5
@User Plz odnoszą się do tego też. Jeśli nie masz jeszcze jasne, plz się o pomoc stackoverflow.com/questions/11772553/...
Jeyaram

Ktokolwiek powiedział, że te bajty wypełniające są bez znaczenia, nie wie, że niedopasowany dostęp do danych jest osobliwością architektury x86. Te bajty są niezbędne, aby uniknąć wyjątków, gdy procesor próbuje załadować - powiedzmy liczbę całkowitą - dane, które przekraczają jego naturalną granicę wyrównania.
Tanveer Badar

86
  • packedoznacza, że ​​wykorzysta jak najmniejszą możliwą przestrzeń struct Ball- tj. będzie upychać pola razem bez wypełnienia
  • alignedoznacza, że ​​każdy struct Ballbędzie zaczynał się od 4-bajtowej granicy - czyli dla każdego struct Ball, jego adres można podzielić przez 4

To są rozszerzenia GCC, nie będące częścią żadnego standardu C.


17

Atrybut packedoznacza, że ​​kompilator nie doda wypełnienia między polami pliku struct. Wypełnienie jest zwykle używane w celu wyrównania pól do ich naturalnego rozmiaru, ponieważ niektóre architektury nakładają kary za niewyrównany dostęp lub w ogóle go nie zezwalają.

aligned(4) oznacza, że ​​struktura powinna być wyrównana do adresu, który jest podzielny przez 4.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.