c - 了解打破严格别名的后果

标签 c struct unions strict-aliasing

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/

相关文章:

c++ - std::map<> 的自定义键

c - 数组处理的性能差异

c - 在 c 中的结构中放置一个 union 是什么意思?

c - 如何在位域结构中输入常量字段

比较接口(interface)的 ipv4 地址和数据包的源地址(libpcap)

c - 如何在不使用 Malloc 的情况下使 typedef 尽可能私有(private)?

c - 通过省略号发送时 `long` 和 `size_t` 的整数提升?

C 中用户定义数据类型的 const 说明符

c - 如何使用指向结构体的指针调用函数?

c - 如何在 C 中的结构内、 union 内使用结构?