std :: tuple内存对齐 [英] std::tuple memory alignment

查看:301
本文介绍了std :: tuple内存对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于元组的伪成员,布局和内存对齐是否有正式规范?



有没有修改元组中类型的内存对齐?是否通过#pragma pack()指令实现?



例如:

  typedef std :: tuple< uint8_t,uint32_t> myTuple; 

有没有说明这将在内存中相同的规格:

  #pragma pack()//默认包装
struct myStruct
{
uint8_t first;
uint32_t second;
}

如果这是一个愚蠢的问题,但我不完全理解对齐,

目前我有一些类似于...

  #pragma pack(push)
#pragma pack(4)
struct cTriangle
{
uint32索引[3];
};
#pragma pack(pop)

template< class T>
inline bool Read(cFileStream& fStream,std :: vector< T>& vec)
{
if(!vec.size())
return true;

// fStream.Read(void * pBuffer,size_t Size)
//只是一个包装二进制ifstream真的
return fStream.Read(& vec [0] ,sizeof(T)* vec.size());
}

std :: vector< cVector3> vPoint;
vPoint.resize(Verticies);
bool result = Read(FileStream,vPoint);



如果我想将typedef cTriangle code> std :: tuple< uint32,uint32,uint32> 为了元编程目的,我仍然能够读/写元组的原始内存(因此元组的向量)或者那个内存有未知的对齐方式?

解决方案

元组通常不是标准布局,因为标准布局类一个类在其非静态数据成员的继承层次结构中,实现变量 tuple 的典型方法是通过递归继承,每个递归级别都添加一个数据成员。这允许 tuple 实现通过空基类优化来清除不同的空成员,这不能用于 struct 成员。



如果您检查 sizeof(myTuple)== sizeof(myStruct),您有理由假设元组的内存布局以一些(一致的)顺序包含结构的元素,但是实际上依赖于别名的元素可能会导致未定义的行为。



假设你只需要使用 tuple 的别名来进行元编程,那么最好使用元编程库,例如 Boost.Fusion ,它允许用其成员来注释struct类型:

  pragma pack(push)
#pragma pack(4)
struct cTriangle {
uint32 Index [3];
};
#pragma pack(pop)
BOOST_FUSION_ADAPT_STRUCT(
cTriangle,
(uint32 [3],Index))


Is there any formal specification for the layout and memory alignment for the pseudo members of a tuple?

Is there anyway to modify the memory alignment of types in a tuple? Is it effected by a #pragma pack() directive?

For example:

typedef std::tuple<uint8_t, uint32_t> myTuple;

Is there any specification that says this will be in memory the same as:

#pragma pack() // Default packing
struct myStruct
{
    uint8_t first;
    uint32_t second;
}

Apologies if this is a stupid question but I don't entirely understand alignment when it comes to templates.

Edit: Example of what I'm trying to accomplish

Currently I have something along the lines of...

#pragma pack(push)
#pragma pack(4)
struct cTriangle
{
    uint32 Index[3];
};
#pragma pack(pop)

template <class T>
inline bool Read(cFileStream& fStream, std::vector<T>& vec)
{
    if (!vec.size())
        return true;

    // fStream.Read(void* pBuffer, size_t Size)
    // Just a wrapper around a binary ifstream really
    return fStream.Read(&vec[0], sizeof(T) * vec.size());
}

std::vector<cVector3> vPoint;
vPoint.resize(Verticies);
bool result = Read(FileStream, vPoint);

If I wanted to typedef cTriangle as std::tuple<uint32, uint32, uint32> for metaprogramming purposes would I still be able to read/write to the raw memory of the tuple (and thus a vector of tuples) or would that memory have unknown alignment?

解决方案

Tuples are typically not standard-layout, because standard-layout classes can have at most one class in their inheritance hierarchy with non-static data members, and the typical way to implement variadic tuple is through recursive inheritance, with each level of recursion adding one data member. This allows tuple implementations to elide distinct empty members through the empty base class optimisation, which is not available for struct members.

If you check that sizeof(myTuple) == sizeof(myStruct), you are reasonably entitled to assume that the memory layout of the tuple contains the elements of the struct in some (consistent) order, but actually relying on that for aliasing will likely cause undefined behaviour.

If as you say you just want alias with tuple for metaprogramming, you'd be better off using a metaprogramming library such as Boost.Fusion that allows you to annotate the struct type with its members:

#pragma pack(push)
#pragma pack(4)
struct cTriangle {
    uint32 Index[3];
};
#pragma pack(pop)
BOOST_FUSION_ADAPT_STRUCT(
    cTriangle,
    (uint32[3], Index))

这篇关于std :: tuple内存对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆