我想我真的在问:别名是“可传递的”吗?如果编译器知道 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)给出了上面的输出,其中 *i
和 u.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]/1In 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/