@ M.M: Стандарт не признает разницу между непосредственным использованием агрегатного элемента и использованием его адреса и его использованием, а также в правилах псевдонимов не проводится различие между структурами и объединениями. Вместо этого поддержка практически любого вида доступа членов является проблемой качества реализации. Так получилось, что существующие версии gcc и clang поддерживают более гибкую семантику с указателями на элементы структуры, чем с lvalues доступа к struct-member, но менее гибкую семантику с указателями на члены union, чем lvalues для доступа union-member.
ми определениями:
struct My_Header { uintptr_t bits; }
struct Foo_Type { struct My_Header header; int x; }
struct Foo_Type *foo = ...;
struct Bar_Type { struct My_Header header; float x; }
struct Bar_Type *bar = ...;
Правильно ли говорить, что это код C ("первый случай"):
foo->header.bits = 1020;
... на самом деле отличаетсясемантически из этого кода ("Случай два"):
struct My_Header *alias = &foo->header;
alias->bits = 1020;
Насколько я понимаю, они должны быть разными
В первом случае назначение не может повлиять на заголовок в Bar_Type. Это рассматривается только как возможность влиять на заголовок в других экземплярах Foo_Type.
Второй случай - принудительный доступ через общий указатель псевдонимов - заставит оптимизатор понять, что все ставки отключены для любого типа, который может содержатьstruct My_Header
, Это было бы синхронизировано с доступом через любой тип указателя.(например, если у вас былFoo_Type
который указывал на то, что на самом делеBar_Type
, он может получить доступ через заголовок и надежно выяснить, что у него было - при условии, что это то, что биты заголовка могли бы сказать вам.)
Это полагается на то, что оптимизатор не станет «умным» и вернет второй случай к первому.