首页 > 解决方案 > union with eigen data types

问题描述

I have been testing Eigen library datatypes with union for type punning. My intent is to have a single memory of double array that can be accessed as an eigen data type and vice versa.

example:

union BigBox{
    double X[13];
    struct
    {
        Eigen::Vector3d p;
        Eigen::Vector3d v;
        Eigen::Vector3d w;
        Eigen::Vector4d q;
    } data;

};

When I test the

sizeof(BigBox)/sizeof(double) = 14
sizeof(Eigen::Vector3d)/sizeof(double) = 3
sizeof(Eigen::Vector4d)/sizeof(double) = 4

The size of the struct does not add up. How does the extra +1 get allotted? I believe it could be because of the compiler trying to exploit the SMID features but is there any way for me to use type punning in these situations? What is the correct approach for what I am trying to achieve?

标签: c++eigenunions

解决方案


默认情况下,Eigen::Vector4d是 16 字节对齐的(或者使用 AVX 编译时是 32 字节对齐,更准确地说,它将对齐到EIGEN_MAX_STATIC_ALIGN_BYTES)。这意味着在每个 3*8 字节(=72 字节)的 3 个向量之后,将有 8 个填充字节。您可以通过将最对齐的元素放在开头或在本地禁用对齐来解决它。

这些都不是真正安全的,因为在 C++ 中,联合不应该用于类型双关语——尽管它在实践中经常起作用。

为了更安全一点,您可以执行以下操作:

struct BigBox{
    Eigen::Matrix<double,13,1> X;

    Eigen::Ref<Eigen::Vector3d      > p()       { return X.segment<3>(0); }
    Eigen::Ref<Eigen::Vector3d const> p() const { return X.segment<3>(0); }
    Eigen::Ref<Eigen::Vector3d      > v()       { return X.segment<3>(3); }
    Eigen::Ref<Eigen::Vector3d const> v() const { return X.segment<3>(3); }
    Eigen::Ref<Eigen::Vector3d      > w()       { return X.segment<3>(6); }
    Eigen::Ref<Eigen::Vector3d const> w() const { return X.segment<3>(6); }
    Eigen::Ref<Eigen::Vector4d      > q()       { return X.segment<4>(9); }
    Eigen::Ref<Eigen::Vector4d const> q() const { return X.segment<4>(9); }

};


推荐阅读