Is type-punning through a union unspecified in C99, and has it become specified in C11?

后端 未结 4 1173
野的像风
野的像风 2020-11-22 04:17

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.: t

4条回答
  •  感情败类
    2020-11-22 04:48

    This has always been "iffy". As others have noted a footnote was added to C99 via a Technical Corregendum. It reads as follows:

    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.

    However, footnotes are specified in the Foreword as non-normative:

    Annexes D and F form a normative part of this standard; annexes A, B, C, E, G, H, I, J, the bibliography, and the index are for information only. In accordance with Part 3 of the ISO/IEC Directives, this foreword, the introduction, notes, footnotes, and examples are also for information only.

    That is, the footnotes cannot proscribe behaviour; they should only clarify the existing text. It's an unpopular opinion, but the footnote quoted above actually fails in this regard - there is no such behaviour proscribed in the normative text. Indeed, there are parts such as 6.7.2.1:

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

    In conjunction with 6.5.2.3 (regarding accessing union members with the "." operator):

    The value is that of the named member

    I.e. if the value of only one member can be stored, the value of another member is non-existent. This strongly implies that type punning via a union should not be possible; the member access yields a non-existent value. The same text still exists in the C11 document.

    However, it's clear that the purpose of adding the footnote was to allow for type-punning; it's just that the committee seemingly broke the rules on footnotes not containing normative text. To accept the footnote, you really have to disregard the section that says footnotes aren't normative, or otherwise try to figure out how to interpret the normative text in such a way that supports the conclusion of the footnote (which I have tried, and failed, to do).

    The section you quote:

    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.

    ... has to be read carefully, though. "The bytes of the object representation that do not correspond to that member" is referring to bytes beyond the size of the member, which isn't itself an issue for type punning (except that you cannot assume writing to a union member will leave the "extra" part of any larger member untouched).

提交回复
热议问题