使用字节数组具有单字节对齐方式的结构是否安全



用于分配任意数量的字节和指针算术struct alignas(1) byte {};安全吗?我更喜欢使用这种字节类型而不是 char 数组,因为字节需要转换为另一种类型才能使用。

快速使用示例:

#include <cstring>
#include <iostream>
struct alignas(1) byte {};
class Any
{
byte* mData;
public:
template<class T>
explicit Any(T pValue) : mData(new byte[sizeof(T)]) {
std::memcpy(mData, &pValue, sizeof(T));
}
~Any() {
delete[] mData;
}
template<class T>
auto get() -> T& {
return *(T*)(mData);
}
};
int main()
{
int i = 5;
Any a(i);
std::cout << a.get<int>() << std::endl;
}

不能分配 4 个字节,然后将第一个字节的地址视为 4 字节对象的地址,因为可能存在对齐要求。

例如,在某些硬件平台中,在不是 4 的倍数的地址处访问 4 字节整数是段错误,而不仅仅是性能问题。

您在以下行中使用了 C 样式转换:return *(T*)(mData)。C 型演员表

通过混合使用static_castconst_castreinterpret_cast将一种类型转换为另一种类型

因此,由于const_caststatic_cast不能在不相关的类型之间强制转换,因此此行等同于:return *reinterpret_cast<T*>(mData)

这段代码访问一个reinterpret_cast的结果,c++要求,给定DynamicTypebyte并且AliasedTypeT,以下1必须为真:

  • AliasedType(可能符合简历标准(DynamicType
  • AliasedTypeDynamicType都是指向同一类型的
    指针(可能是多级的,可能是每个级别的CV合格(
  • AliasedType是(可能符合 CV 条件的(signedunsigned变体DynamicType
  • AliasedType是一种聚合类型或union类型,它将上述类型之一保存为元素或非静态成员(递归地包括子聚合的元素和所包含联合的非静态数据成员(:这使得获得指向structunion
    的可用指针变得安全
  • AliasedTypeDynamicType的基类(可能符合 cv 条件(,DynamicType是没有非静态数据成员的标准布局类,AliasedType是其第一个基类
  • AliasedTypecharunsigned charstd::byte:这允许检查任何对象的对象表示为字节数组

如果T符合这些规范之一,那么您的代码无趣,无法从一种类型转换为另一种类型,但这是合法的。如果不是,则您的代码引入了未定义的行为,应被视为有害行为。

最新更新