"__Öznitelik __ ((paketlenmiş, hizalanmış (4)))" ifadesinin anlamı nedir?


122

C dilidir, şöyle yazılmıştır:

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

Lütfen bana bunun anlamını ve bu anahtar kelimenin nasıl kullanılacağını söyleyin.


4
Bu bir "tür özniteliği" .. (Bunu Google'da "C özniteliği paketlenmiş" olarak buldum. Elbette başkaları da en azından

1
Bu soruya bakın - aligned(4)muhtemelen endişelenecek çok şeyiniz yok.
Keith Thompson

Yanıtlar:


157

Cevap vermeden önce size Wiki'den bazı veriler vermek istiyorum


Veri yapısı hizalaması , verilerin bilgisayar belleğinde düzenlenme ve erişilme biçimidir. İki ayrı ancak ilişkili sorundan oluşur: veri hizalama ve veri yapısı doldurma .

Modern bir bilgisayar bir bellek adresinden okuduğunda veya bir bellek adresinden yazdığında, bunu kelime büyüklüğünde yığınlar halinde yapacaktır (örneğin, 32 bitlik bir sistemde 4 baytlık yığınlar). Veri hizalama , verileri kelime boyutunun birkaç katına eşit bir bellek ofsetine koymak anlamına gelir, bu da CPU'nun belleği işleme biçimi nedeniyle sistemin performansını artırır.

Verileri hizalamak için, son veri yapısının sonu ile bir sonrakinin başlangıcı arasına bazı anlamsız baytlar eklemek gerekebilir, bu veri yapısı dolgusudur. .


gcc, yapı dolgusunu devre dışı bırakmak için işlevsellik sağlar. yani, bazı durumlarda bu anlamsız baytlardan kaçınmak için. Aşağıdaki yapıyı düşünün:

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

}sSampleStruct;

sizeof(sSampleStruct)8 yerine 12 olacaktır. Varsayılan olarak, X86'da yapılar 4 bayt hizalamaya doldurulur:

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

}sSampleStruct;

__attribute__((packed, aligned(X)))Belirli (X) boyutlu dolgularda ısrar etmek için kullanabiliriz . X ikinin üsleri olmalıdır. başvurmakBuraya

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

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

bu nedenle yukarıda belirtilen gcc özelliği yapı dolgusuna izin vermez. bu nedenle boyut 8 bayt olacaktır.

Tüm yapılar için aynısını yapmak isterseniz, basitçe hizalama değerini kullanarak istiflenebiliriz. #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)

6
Bellek, verileri 4 baytlık yığınlar halinde depoluyorsa, neden işaretsiz kısaya (2 bayt uzunluğunda) 2 dolgu baytı eklemiyor? veya derleyici yapının 1. ve son üyelerine dolgu baytları ekler mi? lütfen açıklar mısın?
Kullanıcı

5
@User Plz buna da değiniyor. Hâlâ net değilseniz, yardım için gelin stackoverflow.com/questions/11772553/…
Jeyaram

Bu doldurma baytlarının anlamsız olduğunu kim söylediyse, yanlış hizalanmış veri erişiminin x86 mimarisinin bir tuhaflığı olduğunu bilmiyor. Bu baytlar, işlemci doğal hizalama sınırını aşan verileri yüklemeye çalışırken (örneğin bir tamsayı) istisnaları önlemek için gereklidir.
Tanveer Badar

86
  • packed mümkün olan en küçük alanı kullanacağı anlamına gelir struct Ball - yani alanları doldurma olmadan birbirine tıkar
  • alignedher birinin struct Ball4 baytlık bir sınırda başlayacağı anlamına gelir - yani herhangi biri struct Balliçin adresi 4'e bölünebilir

Bunlar GCC uzantılarıdır, herhangi bir C standardının parçası değildir.


17

Öznitelik packed, derleyicinin struct. Dolgu genellikle alanları doğal boyutlarına hizalamak için kullanılır, çünkü bazı mimariler hizalanmamış erişim için cezalar verir veya buna hiç izin vermez.

aligned(4) yapının 4'e bölünebilen bir adrese hizalanması gerektiği anlamına gelir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.