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

时间:2017-08-08 17:12:24

标签: c++ memory c++14

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;
}

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

您在行中使用了C-Style演员:return *(T*)(mData)C-Style casts

  

通过混合static_castconst_castreinterpret_cast

将一种类型转换为另一种类型

因为const_caststatic_cast无法在不相关的类型之间转换,所以这一行等同于:return *reinterpret_cast<T*>(mData)

此代码访问reinterpret_cast的结果,要求DynamicTypebyteAliasedTypeT,{ {3}}:

  
      
  • AliasedType是(可能是cv资格的)DynamicType
  •   
  • AliasedTypeDynamicType都是(可能是多级,可能是每个级别的cv限定)指向相同类型的指针
  •   
  • AliasedTypesigned
  • unsignedDynamicType变体(可能符合cv标准)   
  • AliasedType是一种聚合类型或union类型,它将上述类型之一保存为元素或非静态成员(包括递归地,子聚合和非静态数据成员的元素)包含的联合):这样可以安全地获得指向structunion的可用指针给定指向其非静态成员或元素的指针
  •   
  • AliasedTypeDynamicType的一个(可能是cv限定的)基类,DynamicType是一个没有非静态数据成员的标准布局类,{{1是它的第一个基类
  •   
  • AliasedTypeAliasedTypecharunsigned char:这允许将任何对象的对象表示检查为字节数组
  •   

如果std::byte符合其中一个规范,那么您的代码无趣无法从一种类型转换为另一种类型,但它是合法的。如果不是,那么您的代码会引入未定义的行为,并且应被视为有毒。