我试图在违反严格的别名规则时了解未定义的行为。为了理解它,我阅读了很多关于 SO 的文章。然而,一个问题仍然存在:我真的不明白两种类型的别名是非法的。 cpp-reference状态:
Type aliasing
Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:
- AliasedType and DynamicType are similar.
- AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.
- AliasedType is std::byte, (since C++17)char, or unsigned char: this permits examination of the object representation of any object as an array of bytes.
我还找到了一个 nice example on SO我清楚地看到问题的地方:
int foo( float *f, int *i ) {
*i = 1;
*f = 0.f;
return *i;
}
int main() {
int x = 0;
std::cout << x << "\n"; // Expect 0
x = foo(reinterpret_cast<float*>(&x), &x);
std::cout << x << "\n"; // Expect 0?
}
int
和 float
是不相似的类型,这个程序可能会造成严重破坏。我没有看到和理解的是以下修改:
struct A
{
int a;
};
struct B
{
int b;
};
A foo( A *a, B *b ) {
a->a = 1;
b->b = 0;
return *a;
}
int main() {
A a;
a.a = 0;
std::cout << a.a << "\n"; // Expect 0
a = foo(&a, reinterpret_cast<B*>(&a));
std::cout << a.a << "\n"; // Expect 0?
}
A
和 B
是相似的类型并且一切都很好,或者它们是非法别名并且我有未定义的行为。如果它是合法的,这是因为 A
和 B
是聚合(如果是的话,我需要更改什么才能使其成为未定义的行为)?
任何提示和帮助将不胜感激。
编辑 关于重复的问题
我知道 this发布,但我看不到他们在哪里澄清哪些类型是相似的。至少没有达到我能理解的程度。因此,如果您不关闭此问题,我们将不胜感激。
最佳答案
不,这是不合法的,你有未定义的行为:
8.2.1 Value category [basic.lval]
11 If a program attempts to access the stored value of an object through a glvalue of other than one of the following types the behavior is undefined: 63
(11.1) — the dynamic type of the object,
(11.2) — a cv-qualified version of the dynamic type of the object,
(11.3) — a type similar (as defined in 7.5) to the dynamic type of the object,
(11.4) — a type that is the signed or unsigned type corresponding to the dynamic type of the object,
(11.5) — a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
(11.6) — an aggregate or union type that includes one of the aforementioned types among its elements or nonstatic data members (including, recursively, an element or non-static data member of a subaggregate or contained union),
(11.7) — a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
(11.8) — a char, unsigned char, or std::byte type
63) The intent of this list is to specify those circumstances in which an object may or may not be aliased.
关于c++ - C++ 中的严格别名规则和类型别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51984540/