Re: Union C++ standard

David Brown <david.brown@hesbynett.no>
Sun, 28 Nov 2021 19:00:00 +0100

          From comp.compilers

Related articles
Union C++ standard DrDiettrich1@netscape.net (Hans-Peter Diettrich) (2021-11-25)
Re: Union C++ standard 480-992-1380@kylheku.com (Kaz Kylheku) (2021-11-26)
Re: Union C++ standard gah4@u.washington.edu (gah4) (2021-11-26)
Re: Union C++ standard david.brown@hesbynett.no (David Brown) (2021-11-27)
Re: Union C++ standard derek@NOSPAM-knosof.co.uk (Derek Jones) (2021-11-28)
Re: Union C++ standard david.brown@hesbynett.no (David Brown) (2021-11-28)
Re: Union C++ standard derek@NOSPAM-knosof.co.uk (Derek Jones) (2021-11-29)
Re: Union C++ standard 480-992-1380@kylheku.com (Kaz Kylheku) (2021-11-29)
Re: Union C++ standard david.brown@hesbynett.no (David Brown) (2021-11-29)
Re: Union C++ standard Keith.S.Thompson+u@gmail.com (Keith Thompson) (2021-11-29)
Re: Union C++ standard derek@NOSPAM-knosof.co.uk (Derek Jones) (2021-11-30)
Re: Union C++ standard gneuner2@comcast.net (George Neuner) (2021-11-30)
[2 later articles]
| List of all articles for this month |

From: David Brown <david.brown@hesbynett.no>
Newsgroups: comp.compilers
Date: Sun, 28 Nov 2021 19:00:00 +0100
Organization: A noiseless patient Spider
References: 21-11-004 21-11-008 21-11-009
Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="34846"; mail-complaints-to="abuse@iecc.com"
Keywords: C, types, comment
Posted-Date: 28 Nov 2021 14:42:42 EST
In-Reply-To: 21-11-009
Content-Language: en-GB

On 28/11/2021 13:51, Derek Jones wrote:
> David,
>
>> In C, type-punning via unions is allowed (i.e., fully defined behaviour
>
> That is not true.  Writing into one member and then reading from
> another member is undefined behavior.


No, it is correct. It would be helpful if you looked at the full
published standards, or (as most people do, since they are free) the
final pre-publishing drafts. In particular, they contain the footnotes
that appear to be missing in the format you linked here. Footnotes are
not part of the normative text, but are added for clarification. (Your
reference also misses the standard paragraph numbering, and it is
outdated - not that this particular issue has changed since C was
standardised.)


So, the relevant paragraph is 6.5.2.3p3:


"""
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, 101) and is an lvalue if the first expression is an
lvalue. If the first expression has qualified type, the result has the
so-qualified version of the type of the designated member.
"""


The footnote (101 in C18 - footnote numbers are not consistent between C
standard versions) is:


"""
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.
"""


These quotations are from C18 (draft N2346), which is the current C
standard (until C23 is finalised). They have not changed since C99,
when the footnote was added without a change to the normative text.
This means that as far as the C committee was concerned, using unions
for type-punning has always (since standardisation) been valid in C, but
they realised that the text was unclear and thus added the footnote.
(Arguably, since C90 did not clearly state that type-punning was
defined, the behaviour was in fact undefined - though probably all C
compilers allowed the behaviour.)


> There is a special dispensation for what is known as a
> common initial sequence:
> sentence 1029
> http://c0x.shape-of-code.com/6.5.2.3.html


This is an additional guarantee that has a longer history - it
specifically allows a particular type of access that had been in regular
use from before C was standardised.


>> in the standards), but not in C++ where the language is expected to
>> enforce higher-level aspects of the data.
>
> This is a meaningless statement.


I disagree, but perhaps that is subjective. In C++, accessing a member
of a union other than the one most recently written (or "active") member
is undefined behaviour, unless it matches the "initial sequence" exception.


Some useful references are:


<https://en.cppreference.com/w/c/language/union>
<https://en.cppreference.com/w/cpp/language/union>


While that site does not have the weight of the C or C++ standards, it
is supported by and contributed to by the C and C++ standards committees
and their ISO working groups. The site does not get that kind of thing
wrong.
[I see what the standard says, but I don't see how reinterpreting the
bits from one type to another can be fully defined. I've certainly done
it, but it never seemed very portable. -John]


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.