gpt4 book ai didi

c++ - 除了 memcpy 之外,bit_cast 还会有什么额外的 UB?

转载 作者:行者123 更新时间:2023-11-28 01:14:59 24 4
gpt4 key购买 nike

我有一个类,其目的是将可能具有对齐限制的数据移入或移出数据未对齐的序列化内存缓冲区。我已按如下方式设置和获取处理程序:

#include <cstring>
template<typename T>
struct handle_type {
static inline T get(const void *data) {
T value;
memcpy(&value, data, sizeof(T));
return value;
}
static inline void set(void *data, T value) {
memcpy(data, &value, sizeof(T));
}
};

c++20出来后,我希望它能变成这样:

#include <bit>
template<typename T>
struct handle_type {
union unaligned { char bytes[sizeof(T)]; }; // EDIT: changed from struct
static inline T get(const void *data) {
return std::bit_cast<T>(*(const unaligned*)data);
}
static inline void set(void *data, T value) {
*(unaligned *)data = std::bit_cast<unaligned>(value);
}
};

它会起作用吗?还是我使用的是 inerim 类型(未对齐的结构类型)容易造成问题?

最佳答案

你的 get 函数是 UB,除非用户提供了一个指向 unaligned 对象的指针。您的 set 函数类似于 UB,除非 data 是一个 unaligned 对象。这两种情况都违反了严格的别名。请记住:严格的别名后门是关于一个实际的 char*;这与恰好包含 char* 的对象不同。

此外,set 可能是一个编译错误,完全取决于 unaligned 的实现是否与 T< 具有相同的大小。毕竟,unaligned 可能在末尾有填充。

bit_cast 想要主要处理对象,而不是内存的随机缓冲区。为此,您应该坚持使用 memcpy


<changed to use union instead of struct>

那什么都没有改变;使用 union 并不能保证 union 的大小等于其最大数据成员的大小。来自 [class.union]/2:

The size of a union is sufficient to contain the largest of its non-static data members.

强调:“足够”,而不是“等于”。该标准允许实现使 union 大于其最大数据成员的能力,因为这样的大小仍然“足够”。

关于c++ - 除了 memcpy 之外,bit_cast 还会有什么额外的 UB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58985965/

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