如果没有成员活跃,您可以覆盖工会的内存吗?

问题描述 投票:0回答:1

以下程序负责摆桌子、吃饭和清理桌子。吃饭前和吃饭后,盘子所在的地方都会被清理干净。根据 C++23 标准允许这样做吗?或者这是未定义的行为? 演示

class Dish {
    // ...
};


class Table {
public:
    Table() {
        std::memset(&dish, 0, sizeof(dish));
        ::new (&dish) Dish();
    }

    ~Table() {
        dish.~Dish();
        std::memset(&dish, 0, sizeof(dish));
    }

    void Eat() {
        dish.Eat();
    }

private:
    union { Dish dish; };
};


int main() {
    Table t;
    t.Eat();
}
c++ language-lawyer undefined-behavior unions c++23
1个回答
0
投票

因为

memset
写入对象就好像它是
char
值的序列,所以它不违反严格的别名规则,[basic.lval]/11:

动态类型

T
obj 的对象可以通过 T
ref
类型的泛左值实现类型可访问,如果
T
ref 类似于 ([conv.qual]) :
T
obj, 与
T
obj 对应的有符号或无符号类型,或者
char
unsigned char
std​::​byte
类型。

如果程序尝试通过不可类型访问的泛左值来访问([defns.access])对象的存储值,则行为是未定义的。如果程序为

U
类型的联合调用默认的复制/移动构造函数或复制/移动赋值运算符,其泛左值参数在其生命周期内不表示 cv
U
类型的对象,则行为未定义.

不保证此操作将为对象生成有效值。但这在你的情况下并不重要,因为你显式构造了一个

Dish
对象(因此它的构造函数有责任设置一个有效值,无论之前有什么。)这里没有什么可以让它成为 UB执行
memset
操作。

© www.soinside.com 2019 - 2024. All rights reserved.