调用std::destroy_at处理未构造对象是否符合C++标准?
对未初始化对象调用std::destroy_at是否合法?
你看到的cppreference示例代码如下:
alignas(S) unsigned char storage[sizeof(S)]{}; S uninitialized = std::bit_cast<S>(storage); std::destroy_at(&uninitialized);
要判断这段代码是否合法,核心在于两个关键点:
std::bit_cast<S>(storage)是否能合法创建一个生命周期已启动的S对象- 对这个对象调用
std::destroy_at的行为是否符合标准
1. std::bit_cast的合法性与对象生命周期
根据C++标准,std::bit_cast仅允许在源类型和目标类型大小相同且均为可平凡复制(trivially copyable)类型时使用。对于可平凡复制类型,标准允许通过字节级复制的方式启动对象的生命周期——只要存储满足对齐要求且大小匹配,字节序列复制完成后,对象的生命周期即开始。
在示例中,storage是对齐到S要求的、值初始化(全0)的字节数组,通过bit_cast转换为S类型时,只要S是可平凡复制类型,得到的uninitialized就是一个完全合法、生命周期已启动的S对象。
2. std::destroy_at的行为
std::destroy_at的作用是调用对象的析构函数。对于具有平凡析构函数的类型(可平凡复制类型必然拥有平凡析构函数),调用destroy_at不会执行任何实际操作——标准明确规定,对这类对象调用析构相关操作是安全的,不会触发未定义行为。
如果S不是可平凡复制类型,那么std::bit_cast<S>(storage)本身就违反了标准要求,属于未定义行为,后续的destroy_at自然也不合法。但cppreference的这类示例通常默认针对可平凡复制类型设计,所以在这个前提下,代码是合法的。
内容的提问来源于stack exchange,提问作者Afshin
相关产品推荐
相关产品推荐

