У меня опыт работы на C #. Я новичок в языке низкого уровня, таком как C.
В C # struct
память по умолчанию распределяется компилятором. Компилятор может неявно изменять порядок полей данных или вставлять дополнительные биты между полями. Итак, мне пришлось указать какой-то специальный атрибут, чтобы переопределить это поведение для точного макета.
AFAIK, C struct
по умолчанию не меняет порядок и не выравнивает структуру памяти . Однако я слышал, что есть небольшое исключение, которое очень трудно найти.
Каково поведение разметки памяти C? Что нужно переупорядочивать / выравнивать, а что нет?
источник
#pragma pack
но с более детальным контролем над семантикой._Alignas
.Это
#pragma pack
зависит от реализации, но на практике правило (при отсутствии или подобном) таково:sizeof(T)
байтов.Итак, учитывая следующую структуру:
struct ST { char ch1; short s; char ch2; long long ll; int i; };
ch1
находится по смещению 0s
по смещению 2ch2
находится по смещению 4, сразу после sll
по смещению 8i
находится по смещению 16, сразу после llТак
sizeof(ST)
что 24.Его можно уменьшить до 16 байт, переставив элементы, чтобы избежать заполнения:
struct ST { long long ll; // @ 0 int i; // @ 8 short s; // @ 12 char ch1; // @ 14 char ch2; // @ 15 } ST;
источник
char
члена в свой пример.sizeof(T)
байтов. Например, вdouble
обычных 32-битных архитектурах длина 8 байтов, но часто требуется только 4-байтовое выравнивание . Кроме того, заполнение в конце структуры дополняет только выравнивание самого широкого элемента структуры. Например, структура из 3-х символьных переменных может не иметь заполнения.Вы можете начать с чтения статьи в Википедии о выравнивании структуры данных в чтобы лучше понять выравнивание данных.
Из статьи в Википедии :
Из 6.54.8 прагмы упаковки структуры документации GCC:
источник