bit*_*ask 62 c++ memory-alignment deprecated c++23
我刚刚看到 C++ 23计划弃用std::aligned_storageandstd::aligned_storage_t以及std::aligned_union。std::aligned_union_t
据我所知,在对齐存储中放置新对象并不是特别constexpr友好,但这似乎不是完全丢弃该类型的好理由。这让我假设使用std::aligned_storage和朋友还存在一些我不知道的其他基本问题。那会是什么?
是否有建议替代这些类型?
Ted*_*gmo 64
以下是三段摘录P1413R3:
背景
aligned_*对代码库有害,不应使用。高层次上:
- 使用
aligned_*调用未定义的行为(类型无法提供存储。)- 保证不正确(标准仅要求类型至少与请求的大小一样大,但没有对大小设置上限。)
- 由于多种原因,API 是错误的(请参阅“关于 API”。)
- 由于 API 是错误的,几乎所有用法都涉及相同的重复预工作(请参阅“现有用法”。)
关于 API
std::aligned_*遭受许多糟糕的 API 设计决策的困扰。其中一些是共享的,一些是特定的。至于分享的内容,主要存在三个问题(为了简洁,这里仅列出一个):
reinterpret_cast需要使用才能访问该值没有实例
.data(),甚至有.data实例std::aligned_*。相反,API 要求您获取对象的地址,使用reinterpret_cast<T*>(...)它进行调用,然后最终间接得到结果指针,为您提供一个T&. 这不仅意味着它不能在 中使用constexpr,而且在运行时更容易意外调用未定义的行为。reinterpret_cast要求使用 API 是不可接受的。
建议更换
最简单的替代
aligned_*实际上不是库功能。相反,用户应该使用正确对齐的 数组std::byte,可能需要调用std::max(std::initializer_list<T>).<cstddef>这些可以分别在和标题中找到<algorithm>(本节末尾有示例)。不幸的是,这种替代并不理想。要访问 的值aligned_*,用户必须调用reinterpret_cast该地址来读取字节作为T实例。使用字节数组作为替代并不能避免这个问题。也就是说,重要的是要认识到,继续使用reinterpret_cast它已经存在的地方并不比在以前不存在的地方新引入它那么糟糕。...
上述已接受的停用提案的部分aligned_*后面是一些示例,例如这两个替代建议:
// To replace std::aligned_storage
template <typename T>
class MyContainer {
private:
//std::aligned_storage_t<sizeof(T), alignof(T)> t_buff;
alignas(T) std::byte t_buff[sizeof(T)];
};
Run Code Online (Sandbox Code Playgroud)
// To replace std::aligned_union
template <typename... Ts>
class MyContainer {
private:
//std::aligned_union_t<0, Ts...> t_buff;
alignas(Ts...) std::byte t_buff[std::max({sizeof(Ts)...})];
};
Run Code Online (Sandbox Code Playgroud)