упаковка структуры: как добавить элементы структуры в начале - PullRequest
1 голос
/ 07 апреля 2019

Я реализую двоичное дерево в C89, и я пытаюсь разделить общие атрибуты среди всех структур узлов через композицию.Таким образом, у меня есть следующий код:

enum foo_type
{
    FOO_TYPE_A,
    FOO_TYPE_B
};

struct foo {
    enum foo_type type;
};

struct foo_type_a {
    struct foo base;
    struct foo * ptr;
};

struct foo_type_b {
    struct foo base;
    char * text;
};

Я включаю член типа struct foo во все определения структуры в качестве их начального члена, чтобы обеспечить доступ к значению enum foo_type независимо от того,Тип структуры.Для достижения этого я ожидаю, что указатель на объект структуры указывает на его начальный член, но я не уверен, что в этом случае верно это предположение.С C99 стандарт гласит следующее (см. ISO / IEC 9899: 1999 6.7.2.1 §13)

Указатель на объект структуры, соответствующим образом преобразованный, указывает на его начальный член (или, если этоmember является битовым полем, затем к единице, в которой он находится), и наоборот.Внутри объекта структуры может быть безымянное заполнение, но не в его начале.

Хотя все структуры имеют общий struct foo объект в качестве своего начального члена, заполнение вступает в игру.В то время как struct foo имеет только один элемент размером int, оба элемента struct foo_type_a и struct foo_type_b содержат элементы-указатели, которые в некоторых случаях увеличивают выравнивание и, таким образом, добавляют отступы.

Итак, учитываяВ этом сценарии обеспечивает ли язык программирования C (C89 или любую последующую версию) безопасный доступ к значению struct foo::type через указатель на объект, независимо от того, относится ли этот объект к типу struct foo или включает ли он объект типа struct foo в качестве первого члена, например struct foo_type_a или struct foo_type_b?

1 Ответ

1 голос
/ 07 апреля 2019

Как вы сами цитируете из стандарта C, то, что вы описываете, поддерживается C99 и более поздними версиями.

Похоже, что он также поддерживается C89, поскольку указанный вами язык уже присутствовал в документе ANSI-C 1988 года:

3.5.2.1 Структура и объединение спецификаторов

...

Внутри структурного объекта, элементов, не являющихся битовыми полями, и единиц измерения в которых находятся битовые поля, адреса которых увеличиваются в порядке в котором они заявлены. Указатель на объект структуры, соответственно приведение, указывает на его начальный элемент (или, если этот элемент является битовым полем, затем к единице, в которой он находится), и наоборот. Может поэтому будьте безымянными отверстиями внутри объекта структуры, но не в его начало, по мере необходимости для достижения соответствующего выравнивания.

...