工会不是我经常使用的东西,在看了一些关于它们的其他问题之后,似乎几乎总会有某种警告他们可能无法工作。例如。结构可能有意想不到的填充或字节序差异。
在我正在使用的数学库中遇到过这个,我想知道它是否是一个完全安全的用法。我假设多维数组没有任何额外的填充,并且因为两种定义的类型相同,所以它们可以保证占用完全相同的内存量?
template<typename T> class Matrix44T
{
...
union
{
T M[16];
T m[4][4];
} m;
};
此设置有任何缺点吗?定义的顺序会对它的工作方式产生任何影响吗?
答案 0 :(得分:4)
虽然我在我的Matrix类中完全一样,但我认为这是依赖于实现的,请阅读标准:
标准9.5.1:
在联盟中,最多只有一个数据 会员可以随时活跃, 也就是说,最多只有一个的价值 数据成员可以存储在 工会在任何时候。 [注意:一个特别的 保证是为了简化 工会的使用:如果是POD工会 包含几个POD结构 共享一个共同的初始序列(9.2), 如果是这个POD联盟的一个对象 type包含一个POD结构, 允许检查共同点 任何POD结构的初始序列 成员;见9.2。 ]
然后问题是m
和M
共享一个共同的初始序列,为了回答这个问题,我们看看9.2 / 15:
两种POD-union(第9节)类型 布局兼容,如果他们有 相同数量的非静态数据成员, 和相应的非静态数据 成员(以任何顺序)都有 布局兼容类型(3.9)。
在阅读完之后答案似乎是,严格意义上没有m
和M
与布局兼容。
在实践中,我认为这可以在所有编译器上正常工作。
答案 1 :(得分:1)
如果你遵守规则,填充和结尾差异不会伤害你。
看看这段代码
union { int a; float b; } wrong;
wrong.a = 1;
printf("%f", wrong.b);
这是错误的,因为如果您有成员“a”,那么除了“a”之外的任何读数都是未定义的。
总结一下:不能告诉工会是否安全。这不是定义,不安全,而是它的使用方式。
答案 2 :(得分:0)
没有。这似乎只是在您的假设下使用union
。
我会选择更好的名称,而不是m
和M
,但除此之外,union
是一个不错的用法。