gpt4 book ai didi

c++ - 使用 aligned_storage 时如何避免严格的别名错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:29:54 26 4
gpt4 key购买 nike

我正在使用 std::aligned_storage 作为变体模板的后备存储。问题是,一旦我在 gcc 上启用 -O2,我就开始收到“取消引用类型双关指针将破坏严格别名”的警告。

真正的模板要复杂得多(在运行时检查类型),但生成警告的最小示例是:

struct foo
{
std::aligned_storage<1024> data;

// ... set() uses placement new, stores type information etc ...

template <class T>
T& get()
{
return reinterpret_cast<T&>(data); // warning: breaks strict aliasing rules
}
};

我很确定 boost::variant 做的事情与此基本相同,但我似乎无法找到他们如何避免这个问题。

我的问题是:

  • 如果以这种方式使用 aligned_storage 违反了严格别名,我应该如何使用它?
  • 鉴于函数中没有其他基于指针的操作,get() 中实际上是否存在严格别名问题?
    • 如果 get() 是内联的呢?
    • get() = 4; 怎么样? get() = 3.2?由于 intfloat 是不同的类型,该序列是否可以重新排序?

最佳答案

std::aligned_storage<type_traits> 的一部分;与该头文件的大多数其他成员一样,它只是一些 typedef 的持有者,并不意味着用作数据类型。它的工作是确定大小和对齐方式,并使您成为具有这些特征的 POD 类型。

您不能使用 std::aligned_storage<Len, Align>直接地。您必须使用 std::aligned_storage<Len, Align>::type ,转换后的类型,它是“适合用作大小最大为 Len 且对齐是 Align 的除数的任何对象的未初始化存储的 POD 类型。” ( Align 默认为大于或等于 Len 的最大有用对齐。)

作为 C++ 标准说明,通常是 std::aligned_storage 返回的类型将是 unsigned char 的数组(指定大小)带有对齐说明符。这避免了“无严格别名”规则,因为字符类型可能会为任何其他类型起别名。

所以你可以这样做:

template<typename T>
using raw_memory = typename std::aligned_storage<sizeof(T),
std::alignment_of<T>::value>::type;

template<typename T>
void* allocate() { return static_cast<void*>(new raw_memory<T>); }

template<typename T, typename ...Arg>
T* maker(Arg&&...arg) {
return new(allocate<T>()) T(std::forward<Arg>(arg)...);
}

关于c++ - 使用 aligned_storage 时如何避免严格的别名错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19217364/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com