工会和类型双关 [英] Unions and type-punning

查看:105
本文介绍了工会和类型双关的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在寻找了一段时间,但无法找到一个明确的答案。

I've been searching for a while, but can't find a clear answer.

很多人说,使用工会输入,双关语是不确定的和不好的做法。为什么是这样?我看不出有任何理由为什么它会做任何事情不确定的考虑你写的原始信息的内存不会只是改变它自己的协议(除非它超出了堆栈范围,但是这不是工会的问题,这将是糟糕的设计)。

Lots of people say that using unions to type-pun is undefined and bad practice. Why is this? I can't see any reason why it would do anything undefined considering the memory you write the original information to isn't going to just change of its own accord (unless it goes out of scope on the stack, but that's not a union issue, that would be bad design).

人们引用严格别名规则,但在我看来,要像说你不能这样做,因为你不能做到这一点。

People quote the strict aliasing rule, but that seems to me to be like saying you can't do it because you can't do it.

还有什么是工会如果不输入双关意义呢?我看到的地方,他们都应该被用来使​​用在不同的时间不同的信息相同的内存位置,但为什么再次使用它之前,不只是删除信息?

Also what is the point of a union if not to type pun? I saw somewhere that they are supposed to be used to use the same memory location for different information at different times, but why not just delete the info before using it again?

要总结一下:


  1. 为什么不好用工会类型双关语?

  2. 什么是他们的点,如果不是这样?

的额外信息:我使用的主要是C ++,但想知道的和C.具体我使用工会浮标和原始十六进制之间的转换通过CAN总线发送

Extra information: I'm using mainly C++, but would like to know about that and C. Specifically I'm using unions to convert between floats and the raw hex to send via CAN bus.

推荐答案

要重新迭代,类型,通过夯实工会是完全没有在C(而不是在C ++)。相比之下,使用指针蒙上这样做违反了C99严格别名和存在问题,因为不同类型可能有不同的对齐要求,如果你这样做不对,你可以提出一个SIGBUS。与工会,这是从来没有一个问题。

To re-iterate, type-punning through unions is perfectly fine in C (but not in C++). In contrast, using pointer casts to do so violates C99 strict aliasing and is problematic because different types may have different alignment requirements and you could raise a SIGBUS if you do it wrong. With unions, this is never a problem.

从C标准的相关报价是:

The relevant quotes from the C standards are:

C89部分3.3.2.3§5:

C89 section 3.3.2.3 §5:

如果一个值已经被存储在所述对象的不同部件后联合对象中的一个部件被访问时,该行为是实现定义

if a member of a union object is accessed after a value has been stored in a different member of the object, the behavior is implementation-defined

C11部分6.5.2.3§3:

C11 section 6.5.2.3 §3:

一个后缀前pression其次。运营商和标识符指定结构或联合对象的成员。的值是指定构件的

A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member

具有以下脚注95:

如果用于读取联合对象的内容的部件是不一样的最后用来存储在对象的值的部件,该值的对象重新presentation的适当部分是reinter $ P如在6.2.6中描述$ PTED作为新类型的对象重新presentation(一个过程有时被称为'型双关语'')。这可能是重新presentation一个陷阱。

If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called ‘‘type punning’’). This might be a trap representation.

这应该是非常清楚。

詹姆斯困惑,因为C11部分6.7.2.1§16读

James is confused because C11 section 6.7.2.1 §16 reads

成员最多一个的值可以在任何时间被存储在联合对象

The value of at most one of the members can be stored in a union object at any time.

这似乎是矛盾的,但它不是:与C ++,在C,没有活跃成员的概念,它是prefectly细度过一个不兼容的前pression访问单个存储值类型。

This seems contradictory, but it is not: In contrast to C++, in C, there is no concept of active member and it's prefectly fine to access the single stored value through an expression of an incompatible type.

另见附件C11 J.1§1:

See also C11 annex J.1 §1:

字节对应比去年存入另外一个工会成员的值[是不确定的。

The values of bytes that correspond to union members other than the one last stored into [are unspecified].

在C99,这个用来读

工会成员比存入最后一个其他值[未指定]

The value of a union member other than the last one stored into [is unspecified]

这是不正确的。如附件不规范,也没有评价自己的TC,不得不等待,直到下一次标准修订得到固定。

This was incorrect. As the annex isn't normative, it did not rate its own TC and had to wait until the next standard revision to get fixed.

这篇关于工会和类型双关的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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