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

发布于 2024-09-02 08:23:51 字数 357 浏览 4 评论 0原文

联合并不是我经常使用的东西,在查看了有关它们的其他一些问题之后,似乎总是存在某种它们可能不起作用的警告。例如。结构可能具有意外的填充或字节序差异。

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

template<typename T> class Matrix44T
{
    ...

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

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

Unions aren't something I've used that often and after looking at a few other questions on them here it seems like there is almost always some kind of caveat where they might not work. Eg. structs possibly having unexpected padding or endian differences.

Came across this in a math library I'm using though and I wondered if it is a totally safe usage. I assume that multidimensional arrays don't have any extra padding and since the type is the same for both definitions they are guaranteed to take up exactly the same amount of memory?

template<typename T> class Matrix44T
{
    ...

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

Are there any downsides to this setup? Would the order of definition make any difference to how this works?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月竹挽风 2024-09-09 08:23:51

虽然我在 Matrix 类中做了完全相同的事情,但我认为这是依赖于实现的,请逐字阅读标准:

标准 9.5.1:

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

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

两种 POD 联合(第 9 条)类型是
布局兼容,如果他们有
相同数量的非静态数据成员,
以及相应的非静态数据
成员(以任何顺序)有
布局兼容类型 (3.9)。

读完这篇文章后,答案似乎是,从严格意义上来说,没有 mM 不兼容布局。

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

Although I do exactly the same in my Matrix-class I think this is implementation dependent, reading the standard to the letter:

Standard 9.5.1:

In a union, at most one of the data
members can be active at any time,
that is, the value of at most one of
the data members can be stored in a
union at any time. [Note: one special
guarantee is made in order to simplify
the use of unions: If a POD-union
contains several POD-structs that
share a common initial sequence (9.2),
and if an object of this POD-union
type contains one of the POD-structs,
it is permitted to inspect the common
initial sequence of any of POD-struct
members; see 9.2. ]

The question then is do m and M share a common initial sequence, to answer this we look at 9.2/15:

Two POD-union (clause 9) types are
layout-compatible if they have the
same number of nonstatic data members,
and corresponding nonstatic data
members (in any order) have
layout-compatible types (3.9).

After reading this the answer seems to be, no m and M are not layout-compatible in the strict sense of the word.

In practice I think this will work fine on all compilers though.

梦忆晨望 2024-09-09 08:23:51

如果您遵守规则,填充和字节序差异不会对您造成伤害。

看一下这段代码

union { int a; float b; } wrong;

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

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

总结一下:工会是否安全无法得知。不安全的不是定义,而是它的使用方式。

If you play by the rules, padding and endian differences won't hurt you.

Look at this code

union { int a; float b; } wrong;

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

This is wrong because if you have written member "a", then any reading except from "a" is undefined.

To sum this up: Whether a union is safe cannot be told. It's not the definition, that is unsafe, it's how it is being used.

や莫失莫忘 2024-09-09 08:23:51

不。根据您的假设,这似乎是 union 的良好用法。

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

No. This seems just fine usage of union under your assumptions.

I would have chosen better names and not m and M but other than that it is a nice usage for union.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文