Я реализую двоичное дерево в 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
?