<分区>
我正在尝试理解用于 C 别名分析的所谓“公共(public)初始序列”规则。这个问题不涉及 C++。
具体根据资源(例如CPython PEP 3123 ),
[A] value of a struct type may also be accessed through a pointer to the first field. E.g. if a struct starts with an
int
, thestruct *
may also be cast to anint *
, allowing to writeint
values into the first field.
(强调我的)。
我的问题可以大致表述为“是否能够通过指向第一个成员类型的指针访问结构来穿透嵌套结构?”也就是说,如果访问是通过指针指向的类型(假设类型 struct A
)与第一个成员的类型(假设类型 )不完全相同,会发生什么情况struct B
),但是指向的类型 (struct A
) 与 struct B
、 和“底层”访问具有共同的第一个初始序列只对那个共同的初始序列做?
(我主要对结构感兴趣,但我可以想象这个问题也可能与 union 体有关,尽管我认为 union 体有它们自己的棘手部分 w.r.t. 别名。)
这个措辞可能不太清楚,所以我尝试用如下代码来说明我的意图(也可在 godbolt.org 获得,而且代码似乎编译得很好,达到了预期的效果):
/* Base object as first member of extension types. */
struct base {
unsigned int flags;
};
/* Types extending the "base" by including it as first member */
struct file_object {
struct base attr;
int index;
unsigned int size;
};
struct socket_object {
struct base attr;
int id;
int type;
int status;
};
/* Another base-type with an additional member, but the first member is
* compatible with that of "struct base" */
struct extended_base {
unsigned int flags;
unsigned int mode;
};
/* A type that derives from extended_base */
struct extended_socket_object {
struct extended_base e_attr; /* Using "extended" base here */
int e_id;
int e_type;
int e_status;
int some_other_field;
};
/* Function intended for structs "deriving from struct base" */
unsigned int set_flag(struct base *objattr, unsigned int flag)
{
objattr->flags |= flag;
return objattr->flags;
}
extern struct file_object *file;
extern struct socket_object *sock;
extern struct extended_socket_object *esock;
void access_files(void)
{
/* Cast to pointer-to-first-member-type and use it */
set_flag((struct base *)file, 1);
set_flag((struct base *)sock, 1);
/* Question: is the following access defined?
* Notice that it's cast to (struct base *), rather than
* (struct extended_base *), although the two structs share the same common
* initial member and it is this member that's actually accessed. */
set_flag((struct base *)esock, 1);
return;
}