int main()
{
struct { int x; } foo;
dostuff(&foo);
return 0;
}
void dostuff(void *ptr)
{
struct { int x; } *p = ptr;
p->x = 5;
}
取消引用 p
是一种严格的别名违规,因为两个未命名的结构不能相互别名,因为它们不兼容。
现在在这样的代码中可能/将会出现什么问题?
编辑: 我仍然不确定这是否是定义的行为,因为它们没有相同的标签。
假设它们不兼容,以下会有什么不同吗?
union u {
void *v;
struct {
int x;
} *p;
};
void dostuff(void *ptr)
{
union u tmp = {.v = ptr};
tmp.p->x = 5;
}
最佳答案
它可能看起来很奇怪|疯狂|令人惊讶|自相矛盾,struct { int x; }
和 struct { int x; }
在一个翻译单元中确实声明了不同的类型,如 e 中所述。 G。 this comment .
would the following make any difference?
union u { void *v; struct { int x; } *p; }; void dostuff(void *ptr) { union u tmp = {.v = ptr}; tmp.p->x = 5; }
您没有在此处指定如何调用 dostuff()
,因此您必须记住与第一个示例相同的 main()
;鉴于此,如果参数在同一翻译单元中声明,则类型仍然不兼容 - 结构类型的两个声明再次声明不同的类型,无论其中一个包含在 union 中。
此外,dostuff()
的第二个版本将 void *v
重新解释为 struct … *p
;由于 C 标准不保证指向 void
的指针与指向结构类型的指针具有相同的表示形式,因此这种用法并不严格符合。
关于c - 了解打破严格别名的后果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27261633/