是否通过 C99 中未指定的联合进行类型双关,并且它是否已在 C11 中指定? [英] Is type-punning through a union unspecified in C99, and has it become specified in C11?

查看:26
本文介绍了是否通过 C99 中未指定的联合进行类型双关,并且它是否已在 C11 中指定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

堆栈溢出问题的一些答案获取IEEE Single-precision bits for a float 建议使用 union 结构进行类型双关(例如:将 float 的位转换为 uint32_t):

A number of answers for the Stack Overflow question Getting the IEEE Single-precision bits for a float suggest using a union structure for type punning (e.g.: turning the bits of a float into a uint32_t):

union {
    float f;
    uint32_t u;
} un;
un.f = your_float;
uint32_t target = un.u;

但是,根据 C99 标准(至少是草案 n1124),联合的 uint32_t 成员的值似乎未指定,其中第 6.2.6.1.7 节规定:

However, the value of the uint32_t member of the union appears to be unspecified according to the C99 standard (at least draft n1124), where section 6.2.6.1.7 states:

当一个值存储在联合类型对象的成员中时,对象表示中与该成员不对应但与其他成员对应的字节采用未指定的值.

When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.

C11 n1570 草案的至少一个脚注似乎暗示这不再是这种情况(参见 6.5.2.3 中的脚注 95):

At least one footnote of the C11 n1570 draft seems to imply that this is no longer the case (see footnote 95 in 6.5.2.3):

如果用于读取联合对象内容的成员与上次用于读取的成员不同在对象中存储一个值,该值的对象表示的适当部分被重新解释作为 6.2.6 中描述的新类型中的对象表示(有时称为类型双关语'').这可能是一个陷阱表示.

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.

但是,C99 草案中的第 6.2.6.1.7 节的文本与 C11 草案中的相同.

However, the text to section 6.2.6.1.7 is the same in the C99 draft as in the C11 draft.

这种行为在 C99 下实际上是未指定的吗?是否已在 C11 中指定?我意识到大多数编译器似乎都支持这一点,但很高兴知道它是在标准中指定的,还是只是一个非常常见的扩展.

Is this behavior actually unspecified under C99? Has it become specified in C11? I realize that most compilers seem to support this, but it would be nice to know if it's specified in the standard, or just a very common extension.

推荐答案

类型双关的行为从 C89 更改为 C99.C99 中的行为与 C11 相同.

The behavior of type punning with union changed from C89 to C99. The behavior in C99 is the same as C11.

正如 Wug 在他的回答中指出的那样,C99/C11 中允许使用双关语.当联合成员的大小不同时,会读取可能是陷阱的未指定值.

As Wug noted in his answer, type punning is allowed in C99 / C11. An unspecified value that could be a trap is read when the union members are of different size.

脚注是 C99 在 Clive D.W. 之后添加的.Feather 缺陷报告#257:

The footnote was added in C99 after Clive D.W. Feather Defect Report #257:

最后,从 C90 到 C99 的更改之一是取消了当最后一个商店指向不同的商店时访问联合的一个成员的任何限制. 基本原理是,该行为将随后取决于值的表示.由于这一点经常被误解,因此可能值得在标准中明确说明.

Finally, one of the changes from C90 to C99 was to remove any restriction on accessing one member of a union when the last store was to a different one. The rationale was that the behaviour would then depend on the representations of the values. Since this point is often misunderstood, it might well be worth making it clear in the Standard.

[...]

为了解决关于类型双关语"的问题,在 6.5.2.3#3 中的命名成员"一词上附加一个新的脚注 78a:78a 如果用于访问联合对象内容的成员与上次用于在对象中存储值的成员不同,则将值的对象表示的适当部分重新解释为新类型中的对象表示如 6.2.6 中所述(有时称为类型双关语"的过程).这可能是一个陷阱表示.

To address the issue about "type punning", attach a new footnote 78a to the words "named member" in 6.5.2.3#3: 78a If the member used to access 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.

克莱夫 D.W. 的措辞在 C 委员会对 缺陷报告 #283.

The wording of Clive D.W. Feather was accepted for a Technical Corrigendum in the answer by the C Committee for Defect Report #283.

这篇关于是否通过 C99 中未指定的联合进行类型双关,并且它是否已在 C11 中指定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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