Компоновка структуры определяется реализацией. И оказывается, что макет по умолчанию, используемый GCC, отличается от макета, используемого, например, MSVC. Я предполагаю, что вы привыкли к тому, как MSVC размещает структуры, содержащие битовые поля.
Конечно, есть атрибут GCC, ms_struct
, позволяющий изменить поведение. Более подробно это описано в документации. .
Итак, эта структура имеет размер 16:
struct abc
{
char arr[7];
char arr1[2];
int i:24;
} __attribute__((ms_struct));
Если вы используете параметр gcc_struct
по умолчанию, размер равен 12.
Для конкретной реализации, где я могу получить документацию, описывающую, как конкретный компилятор (например, GCC) вводит заполнение в структуру?
Вам необходимо ознакомиться с документацией каждого компилятора. В случае GCC документация говорит:
4.9. Структуры, объединения, перечисления и битовые поля
Доступ к члену объекта объединения осуществляется с использованием члена другого типа (C90 6.3.2.3).
Соответствующие байты представления объекта обрабатываются как объект того типа, который используется для доступ. См. каламбур. Это может быть представление-ловушка.
Обрабатывается ли «простое» битовое поле int как битовое поле int со знаком или как битовое поле int без знака (C90 6.5.2, C90 6.5.2.1, C99 6.7.2, C99 6.7.2.1).
По умолчанию считается целым числом со знаком, но это можно изменить с помощью параметра -funsigned-bitfields.
Допустимые типы битовых полей, отличные от _Bool, signed int и unsigned int (C99 6.7.2.1).
В режиме строгого соответствия никакие другие типы не разрешены.
Может ли битовое поле пересекать границу единицы хранения (C90 6.5.2.1, C99 6.7.2.1).
Определяется ABI.
Порядок размещения битовых полей в блоке (C90 6.5.2.1, C99 6.7.2.1).
Определяется ABI.
Выравнивание элементов структур, не являющихся битовыми полями (C90 6.5.2.1, C99 6.7.2.1).
Определяется ABI.
Целочисленный тип, совместимый с каждым перечисляемым типом (C90 6.5.2.2, C99 6.7.2.2).
Обычно типом является unsigned int, если в перечислении нет отрицательных значений, в противном случае — int. Если указан -fshort-enums, то при наличии отрицательных значений это первый из signed char, short и int, который может представлять все значения, в противном случае это первый из unsigned char, unsigned short и unsigned int, который может представлять все значения. значения.
Для некоторых целей по умолчанию используется -fshort-enums; это определяется ABI.
Итак, по большому счету, вам нужно выяснить, что такое ABI для вашей платформы. Это действительно разумная вещь для любого компилятора. Если он не размещает структуры в соответствии с ABI, то это делает взаимодействие чрезвычайно сложным.
Что немного странно, так это то, что взгляд GCC на то, что такое ABI в Windows, отличается от реализации MSVC. У меня нет понимания, почему это так.
person
David Heffernan
schedule
14.04.2013
char
не нуждаются в выравнивании, аi
представляет собой трехбайтовое битовое поле, поэтому 7+2+3=12. - person Sergey Kalinichenko   schedule 14.04.2013arr
— семь байтов,arr1
— два байта,i
— три байта. - person Sergey Kalinichenko   schedule 14.04.2013