使用联合时未定义行为的情况

A case of undefined behaviour when using a union

本文关键字:情况 未定义      更新时间:2023-10-16

我有以下代码来自"详细C++17"一书:

union Superfloat{
float f;
int i;
}
int RawMantissa(Superfloat f){
return f.i & ((1< 23) -1);
}
int RawExponent(Superfloat f){
return (f.i >> 23)& 0xFF;
}

在那段代码之后,Bartlomiej Filipek先生写道: "然而,虽然上面的代码可能在 C99 中工作,但由于更严格的 alizing 规则,它在 C++ 中是未定义的行为"。

我想更好地理解作者这句话的意思,因为我不明白。 你能详细解释一下吗?

他给出了以下解释(但我需要更多的解释(:

约183...读取与写入时不同类型的工会成员是未定义的。这种双关语是看不见的,或者至少比使用命名的>演员更难发现......

我也不明白这种解释,以及它如何帮助理解上面的代码是未定义的行为。

我将感谢您的深刻解释

这很简单。工会最多有一个活跃成员。当您写入成员时,该成员将变为活动状态。您只能从活动成员读取。

例:

union U
{
float f;
int i;
};
auto foo_1()
{
U u; // no member is active
u.f = 24.5; // write to `u.f` . `u.f` is now the active member
int i = u.i; // read of `u.i` Since `u.i` is not the active member this is UB in C++
}
auto foo_2()
{
U u;
// no active member
u.f = 24.5; // write to `u.f` . `u.f` is now the active member
float f = u.f; // read of `u.f` . Ok since `u.f` is the active member
u.i = 11; // write to `u.i` . `u.i` is now the active member.
// `u.f` is NOT the active member anymore
int i = u.i; // ok, read of the active member `u.i`
float f2 = u.f; // read of `u.f`. UB, since `u.f` is not the active member
}