假设定义了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中的结构扩展
发布评论