在这个矩阵类中使用union是否完全安全?

时间:2010-05-21 09:58:38

标签: c++ templates matrix unions

工会不是我经常使用的东西,在看了一些关于它们的其他问题之后,似乎几乎总会有某种警告他们可能无法工作。例如。结构可能有意想不到的填充或字节序差异。

在我正在使用的数学库中遇到过这个,我想知道它是否是一个完全安全的用法。我假设多维数组没有任何额外的填充,并且因为两种定义的类型相同,所以它们可以保证占用完全相同的内存量?

template<typename T> class Matrix44T
{
    ...

    union
    {
        T M[16];
        T m[4][4];
    } m;
};

此设置有任何缺点吗?定义的顺序会对它的工作方式产生任何影响吗?

3 个答案:

答案 0 :(得分:4)

虽然我在我的Matrix类中完全一样,但我认为这是依赖于实现的,请阅读标准:

标准9.5.1:

  

在联盟中,最多只有一个数据   会员可以随时活跃,   也就是说,最多只有一个的价值   数据成员可以存储在   工会在任何时候。 [注意:一个特别的   保证是为了简化   工会的使用:如果是POD工会   包含几个POD结构   共享一个共同的初始序列(9.2),   如果是这个POD联盟的一个对象   type包含一个POD结构,   允许检查共同点   任何POD结构的初始序列   成员;见9.2。 ]

然后问题是mM共享一个共同的初始序列,为了回答这个问题,我们看看9.2 / 15:

  

两种POD-union(第9节)类型   布局兼容,如果他们有   相同数量的非静态数据成员,   和相应的非静态数据   成员(以任何顺序)都有   布局兼容类型(3.9)。

在阅读完之后答案似乎是,严格意义上没有mM与布局兼容。

在实践中,我认为这可以在所有编译器上正常工作。

答案 1 :(得分:1)

如果你遵守规则,填充和结尾差异不会伤害你。

看看这段代码

union { int a; float b; } wrong;

wrong.a = 1;
printf("%f", wrong.b);

这是错误的,因为如果您有成员“a”,那么除了“a”之外的任何读数都是未定义的。

总结一下:不能告诉工会是否安全。这不是定义,不安全,而是它的使用方式。

答案 2 :(得分:0)

没有。这似乎只是在您的假设下使用union

我会选择更好的名称,而不是mM,但除此之外,union是一个不错的用法。