【发布时间】:2015-01-31 10:05:36
【问题描述】:
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;
}
【问题讨论】:
-
如果您违反严格的别名,则会导致未定义的行为,这意味着任何事情都可能发生。
-
如果这两个函数在两个不同的文件中,由不同的编译器编译(甚至同一编译器的不同版本/设置),那么您可能会遇到不同的打包/对齐等问题。跨度>
-
阅读标准后,我不确定这些结构是否实际上不兼容。这实际上可能已定义。
-
也许我错了。但是,正如我所看到的,a 正在将指向某些数据的指针传递给保存该指针的第二个函数。对我来说似乎没问题。当然,如果我想要这样的东西,我会在头文件中声明结构格式,并让每个 .c 文件都包含该头文件。
-
所以如果这是未定义的行为,那么我的问题的答案是,直截了当地说:别这样,这是UB,任何事情都可能发生,对吗?但现在我不太确定它是否真的是未定义的
标签: c struct unions strict-aliasing