https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65892

Davin McCall <davmac at davmac dot org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |davmac at davmac dot org

--- Comment #25 from Davin McCall <davmac at davmac dot org> ---
(In reply to Tim Rentsch from comment #21)
>
> Three:  The "one special guarantee" rule is independent of the
> rules for effective types.  This observation is obviously right
> because effective type rules matter only for access to objects.
> The only objects being accessed under the "one special guarantee"
> rule are guaranteed to have compatible types, which is always
> allowed by effective type rules.

However, the two structures are not compatible types; in a union as per the
example at the head of this PR -

union U {
    struct t1 { int m; } s1;
    struct t2 { int m; } s2;
};

- the types 'struct t1' and 'struct t2' are not compatible. This line:

        p2->m = -p2->m;

- is accessing the active union member (s1) via an incompatible type. From
6.5.2.3:

"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
of the object to which the first expression points"

This makes it IMO clear enough that the structure object is being accessed,
since you can't extract the member of an object without the object existing. If
that were not the case, then you could *always* use p2->m to access the 'm'
member of a 'struct t1' object regardless of the existence of a suitable union
declaration, unless you interpret the "special guarantee" just to mean that the
layout of a C.I.S. need only be identical between two structs if those structs
are part of the same union. In that case however there is no reason for
visibility of the union to matter at point of access, since the struct layout
surely cannot be different in different parts of the program (i.e. if two
structs are visible in a union anywhere and this forces common layout of the
C.I.S, then the C.I.S must have the same common layout throughout the program;
it doesn't make sense to require visibility of the union declaration to make
use of the "special guarantee").

> Four:  The "one special guarantee" rule is related to the area of
> "type punning" through unions, but seen by WG14 as a separate
> issue relative to the general topic.  This is evident from the
> committee response in DR 257.

It's problematic though that the committee response doesn't really follow from
the text. You cannot access the member of one structure via a pointer to
another structure with the same layout, as I have shown above, due to the
aliasing rules. If you (or WG14) are claiming that the "special guarantee" is
not directly concerned with aliasing, then the only way you could make use of
the rule is anyway via type punning, and the only way we can do that without
violating aliasing rules is to go via the union object, at which point the
question of union declaration visibility is moot.

> Five:  The footnote added in C99 TC3 about type punning is seen
> by WG14 not as a change but just as a clarifying comment noting
> what behavior was intended all along.  This is evident from the
> text and response in DR 283.  Note that Clark Nelson, the author
> of this DR, is a long-standing member of WG14, and the suggested
> revision given in the text was adopted verbatim for the TC.

While I agree that this is what WG14 seem to believe, I see no normative part
of the text which supports the footnote, and I see some parts which contradict
it (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" / 6.5.2.3 "The value is that of the named member of
the object to which the first expression points" - if the value of only one
member can be stored, how can the value of any other member be defined?).

Reply via email to