Reading this http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html我理解,如果结构具有兼容的成员,则可以为结构添加别名(即不违反标准),即给出以下结构:
typedef struct {
uint32_t a;
uint32_t b;
} Frizzly;
以下内容会破坏别名规则:
uint32_t foo(uint16_t *i) {
Frizzly *f = (Frizzly *)i;
return f->a;
}
但以下情况则不会:
uint32_t foo(uint32_t *i) {
Frizzly *f = (Frizzly *)i;
return f->b;
}
因为所讨论的“聚合类型”包含与我们要转换为它的指针兼容的类型,即指向类型的指针uint32_t
可以转换为包含类型成员(或成员)的结构uint32_t
不违反别名规则。
首先,我的理解正确吗?
其次,结构中(其他)变量的顺序和类型重要吗?说,如果Frizzly
定义如下:
typedef struct {
uint16_t b[2];
uint32_t a;
}
在第二个示例中进行转换后,b
现在由不兼容的内存支持(uint32_t
) 类型。强制转换仍然有效(或者更确切地说,通过强制转换的指针访问值)?将更改以下任一元素a
改变第一个元素的值i
(反之亦然)就像严格别名被禁用一样?
另外,如果上述是有效的,如果我有一个像这样的结构怎么办:
typedef struct {
void *m;
uint16_t hooah[4];
} Bar;
如果我是正确的,以下转换将打破别名规则:
void test(char *boo, size_t dee) {
Bar *bar = (Bar *)(boo + dee);
do_other_stuff(bar);
}
我可以简单地通过添加一个来使演员阵容有效吗unsigned char
成员进入结构体?换句话说,不兼容类型的指针转换通常会破坏别名规则,但由于从指针到包含类型成员的结构的转换X
变成一个指向X
是一个例外,是否可以通过将 X 类型的(可能是虚拟的)成员添加到 Y 中来使从 X 指针到聚合 Y 的任何转换都有效?
(我实际上没有在编译器中测试上述代码片段。)
EDIT:
我知道我的措辞和示例可能相当糟糕,所以我将尝试重新表述这个问题:如果我理解正确,那么只要满足以下条件,指向结构的指针为类型为“X”的元素数组添加别名是合法的该结构包含类型“X”的成员。现在,当取消引用结构体的成员时,该成员是否必须是“X”类型,或者是严格别名规则的例外all结构体的成员无论其类型如何,只要有一个适当类型的成员即可?