Яке значення “__attribute __ ((упаковано, вирівняно (4)))”


122

Це мова С. Написано, що:

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

Скажіть, будь ласка, у чому сенс цього питання та як користуватися цим ключовим словом.


4
Це "атрибут типу" .. (Я знайшов це в "Google атрибуті, упакованому" в Google. Напевно, інші можуть принаймні зробити так добре!)

1
Подивіться на це запитання - хоча з aligned(4)вами, мабуть, не варто багато хвилюватися.
Кіт Томпсон

Відповіді:


157

Перш ніж відповісти, я хотів би надати вам деякі дані з Вікі


Вирівнювання структури даних - це спосіб упорядкування та доступу до даних у пам'яті комп'ютера. Він складається з двох окремих, але пов’язаних із цим питань: вирівнювання даних та доповнення структури даних .

Коли сучасний комп’ютер читає або записує на адресу пам'яті, він буде робити це в шматки розміру слова (наприклад, 4 байтні фрагменти в 32-бітній системі). Вирівнювання даних означає приведення даних у зсув пам'яті, рівний деякому кратному розміру слова, що збільшує продуктивність системи завдяки тому, як процесор обробляє пам'ять.

Для вирівнювання даних може знадобитися вставити кілька безглуздих байтів між кінцем останньої структури даних та початком наступної, що є вкладкою структури даних .


gcc надає функціональність для відключення заміщення структури. тобто уникати цих безглуздих байтів у деяких випадках. Розглянемо таку структуру:

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

}sSampleStruct;

sizeof(sSampleStruct)буде 12, а не 8. Через прокладку конструкції. За замовчуванням у X86 структури будуть замінені на 4-байтове вирівнювання:

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

}sSampleStruct;

Ми можемо використовувати __attribute__((packed, aligned(X)))для наполягання конкретних (X) розмірів. X повинні бути повноваженнями двох. Зверніться сюди

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

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

тому вищезазначений атрибут gcc не дозволяє структуру набивання. тому розмір складе 8 байт.

Якщо ви хочете зробити те ж саме для всіх структур, просто ми можемо підштовхнути значення вирівнювання до стеку за допомогою #pragma

#pragma pack(push, 1)

//Structure 1
......

//Structure 2
......

#pragma pack(pop)

6
Якщо пам'ять зберігає дані в 4-х байтових фрагментах, то чому вона не додає 2 байтових прокладки до непідписаного короткого (його 2-х байт)? чи компілятор просто додає байти прокладки до 1-го та останнього членів структури? ви можете, будь ласка, уточнити це.
Користувач

5
@User Plz також посилайтеся на це. Якщо ви до цих пір не ясно, плз прийти на допомогу stackoverflow.com/questions/11772553 / ...
Jeyaram

Хто б не сказав, що ці байти прокладки є безглуздими, той не знає, що нерівний доступ до даних - це дивина архітектури x86. Ці байти необхідні, щоб уникнути винятків, коли процесор намагається завантажити - скажімо, ціле число - дані, які стримують його природну межу вирівнювання.
Танвер Бадар

86
  • packedзначить, він буде використовувати найменший можливий простір для struct Ball- тобто він буде збивати поля разом без прокладки
  • alignedозначає, що кожен struct Ballпочинається на 4-байтній межі - тобто для будь-якої struct Ballадреси його можна розділити на 4

Це розширення GCC, які не входять до жодного стандарту C.


17

Атрибут packedозначає, що компілятор не додасть прокладки між полями struct. Засипка зазвичай використовується для вирівнювання полів за їх природним розміром, оскільки деякі архітектури накладають штрафні санкції за несогласований доступ або взагалі не дозволяють цього.

aligned(4) означає, що структуру слід вирівняти за адресою, яка ділиться на 4.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.