gpt4 book ai didi

c - 违反 C 中的严格别名,即使没有任何转换?

转载 作者:太空狗 更新时间:2023-10-29 16:17:21 31 4
gpt4 key购买 nike

*iu.i 如何在此代码中打印不同的数字,即使 i 被定义为 int *i = &u.i;?我只能假设我在这里触发了 UB,但我看不出具体情况。

( 如果我选择“C”作为语言,ideone demo 会复制。但正如@2501 指出的那样,如果“C99 strict”是语言,则不会复制。但是话又说回来,我遇到了 gcc-5.3 的问题.0 -std=c99!)

// gcc       -fstrict-aliasing -std=c99   -O2
union
{
int i;
short s;
} u;

int * i = &u.i;
short * s = &u.s;

int main()
{
*i = 2;
*s = 100;

printf(" *i = %d\n", *i); // prints 2
printf("u.i = %d\n", u.i); // prints 100

return 0;
}

(gcc 5.3.0,带有 -fstrict-aliasing -std=c99 -O2,也带有 -std=c11)

我的理论是 100 是“正确”答案,因为通过 short-lvalue *s 写入 union 成员是这样定义的(对于这个平台/字节顺序/无论什么)。但我认为优化器没有意识到写入 *s 可以别名 u.i,因此它认为 *i=2; 是唯一可以影响 *i 的行。这是一个合理的理论吗?

如果*s可以作为u.i的别名,而u.i可以作为*i的别名,那么编译器肯定应该认为 *s 可以作为 *i 的别名?别名不应该是“可传递的”吗?

最后,我一直认为严格别名问题是由错误的转换引起的。但是这里没有类型转换!

(我的背景是 C++,我希望我在这里问一个关于 C 的合理问题。我的(有限的)理解是,在 C99 中,通过一个 union 成员编写然后通过另一个成员读取是可以接受的不同类型。)

最佳答案

差异是由 -fstrict-aliasing 优化选项发出的。 GCC documentation 中描述了它的行为和可能的陷阱。 :

Pay special attention to code like this:

      union a_union {
int i;
double d;
};

int f() {
union a_union t;
t.d = 3.0;
return t.i;
}

The practice of reading from a different union member than the one most recently written to (called “type-punning”) is common. Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the code above works as expected. See Structures unions enumerations and bit-fields implementation. However, this code might not:

      int f() {
union a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
}

请注意,完全允许符合规范的实现利用此优化,因为第二个代码示例展示了 undefined behaviour .参见 Olaf's和其他人的答案以供引用。

关于c - 违反 C 中的严格别名,即使没有任何转换?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39757658/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com