gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 00:46:05 26 4
gpt4 key购买 nike

我想我真的在问:别名是“可传递的”吗?如果编译器知道 A 可能是 B 的别名,而 B 可能是 C 的别名,那么它肯定应该记住 A 可能因此是 C 的别名。然而,也许不需要这种“明显的”传递逻辑?

为清楚起见,举个例子。对我来说,最有趣的例子是严格别名问题:

// g++    -fstrict-aliasing -std=c++11 -O2
#include <iostream>

union
{
int i;
short s;
} u;
int * i = &u.i;

int main()
{

u.i = 1; // line 1
*i += 1; // line 2

short & s = u.s;
s += 100; // line 3

std::cout
<< " *i\t" << *i << std::endl // prints 2
<< "u.i\t" << u.i << std::endl // prints 101
;

return 0;
}

g++ 5.3.0,在 x86_64 上(但不是 clang 3.5.0)给出了上面的输出,其中 *iu.i 给出了不同的数字。但它们应该给出完全相同的数字,因为 i 定义在 int * i = &u.i; 并且 i 不会改变。

我有一个理论:当“预测”u.i 的值时,编译器会询问哪些行可能会影响u.i 的内容。这显然包括第 1 行。和第 2 行,因为 int* 可以作为 union 的 int 成员的别名。还有第 3 行,因为任何可以影响一个 union 成员 (u.s) 的东西都可以影响同一 union 的另一个成员。但是在预测 *i 时,它没有意识到第 3 行会影响 *i 处的 int 左值。

这个理论看起来合理吗?

我觉得这个例子很有趣,因为我没有在其中进行任何转换。我设法通过进行任何转换来打破严格别名。

最佳答案

从 union 的非事件成员读取在 C++ 中是未定义的。 (它在 C99 和 C11 中是合法的)。

因此,总而言之,编译器不需要假设/记住任何东西。

标准语:

N4140 §9.5[class.union]/1

In a union, at most one of the non-static data members can be active at any time, that is, the value of at most one of the non-static data members can be stored in a union at any time.

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

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