我正在尝试理解违反严格别名规则时的未定义行为。我已经阅读了许多关于此问题的文章,但仍有一个问题:我不太明白两种类型何时非法别名。cpp-reference指出:
"
我还在SO上找到了一个很好的例子,其中我清楚地看到了问题:类型别名
每当试图通过类型为AliasedType的glvalue读取或修改DynamicType类型对象的存储值时,除非以下情况之一成立,否则行为是未定义的:
- AliasedType和DynamicType相似。
- AliasedType是DynamicType的(可能是cv-qualified的)有符号或无符号变体。
- AliasedType是std::byte、(自C++17起)char或unsigned char:这允许将任何对象的对象表示视为字节数组进行检查。
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 帖子,但我没有看到他们澄清哪些类型是相似的。至少我不理解。因此,如果您不关闭此问题,那就太好了。
C
类型的文档引用了“兼容类型”,链接为 https://en.cppreference.com/w/c/language/type ;而C++
文档则没有,链接为 https://en.cppreference.com/w/cpp/language/type 。因此,“兼容类型”对于C++
不相关,而重复的链接解释了其他所有内容。在对象是什么以及如何操作/引用它的领域中,C
和C++
之间存在显着差异。混合使用两个标准的术语可能会导致混淆。 - Richard Critten