C中的结构扩展 [英] Struct Extension in C
问题描述
假设定义了2种结构的广告,例如:
Suppose there are 2 structures defined ad such:
typedef struct {
T x;
T y;
} A;
typedef struct {
A a;
T z;
} B;
我可以将指向结构B的指针视为指向结构A的指针吗?
Can I treat a pointer to structure B as pointer to structure A?
实际上,这个可靠/标准/便携式/编译器不变的变量是:
In practice is this reliable/standard/portable/compiler-invariant:
B b = {{1,2},3};
A * a = &b;
print(a->x);
print(a->y);
推荐答案
C17 6.7.2.1指出了这一点(强调我的意思):
C17 6.7.2.1 states this (emphasis mine):
在结构对象中,非位字段成员和位字段
所在的单元的地址按顺序增加在其中声明它们。 经过适当转换的指向
结构对象的指针指向其初始成员(或者,如果该成员是
位域,则指向它所在的单元) ,,反之亦然。
Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa.
这意味着您必须适当地转换 B b
对象的指针指向其第一个成员的类型。此转换不是隐式发生的,您必须通过显式强制转换来做到这一点:
This means that you must "suitably convert" the pointer for the B b
object into the type of it's first member. This conversion doesn't happen implicitly, you must do this by means of an explicit cast:
A * a = (A*)&b;
按照上面引用的部分,这样做是明确且安全的。
Doing so is well-defined and safe, as per the quoted part above.
类似地,不允许编译器假定指向 A
的指针和指向 B
的指针别名。有效类型6.5.7的规则(严格别名)在这种情况下给出了例外:
Similarly, the compiler is not allowed to assume that a pointer to A
and a pointer to B
don't alias. The rule of effective type 6.5.7 ("strict aliasing") gives an exception for this case:
对象只能通过以下方式访问其存储值:具有以下类型之一的左值表达式:
...
An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
...
- 包括以下类型之一的聚合或并集类型
例如,在优化过程中,编译器调用函数 void func (B * b)
不允许假定外部线性变量 extern A a;
在其他翻译单元中定义的值未被更改功能。
For example, during optimization a compiler calling the function void func (B* b)
is not allowed to assume that a external linage variable extern A a;
defined in some other translation unit was not changed by the function.
这篇关于C中的结构扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!