Skip to content

[class.mem.general] Clarify when access to common initial sequence is allowed #693

Open
@t3nsor

Description

@t3nsor

Full name of submitter: Brian Bi

Issue description: The allowance in [class.mem.general]/29 to read from a member of the common initial sequence of an inactive union member with the active member should be clarified. It is probably intended to apply only to cases where both the inactive union member and its member are explicitly named, as opposed to being accessed through a pointer, reference, or pointer-to-member.

Suggested resolution: Edit [class.mem.general]/29:

In a standard-layout union with an active member of struct type T1, it is permitted to read a non-static data member m of another union member of struct type T2 provided m is part of the common initial sequence of T1 and T2; the behavior is as if the corresponding member of T1 were nominated. Except during the evaluation of an expression as a core constant expression ([expr.const]), when an lvalue-to-rvalue conversion ([conv.lval]) is applied to an expression of the form u . s . m O1 ... On where u is possibly the result of an implicit transformation ([expr.ref], [expr.prim.id.general]), n is possibly zero, and

  • u is of union type and has an active member,
  • s designates an inactive member of u having standard-layout struct type,
  • m designates a member of the common initial sequence of s's type and the type of u's active member, and
  • each element of O has the form
    • . identifier where the identifier designates a non-static data member or
    • [expression] where the left operand is of array type

the result is as if the active member were nominated instead of s, m were replaced by the name of the corresponding member of the active member's type, and for each element of O of the form . identifier, the identifier were replaced by the name of the corresponding member of the type that the left operand would have after all preceding replacements.

[Example 5: ... ]
[Example 5:
struct X { int x; };
struct Y { int y; };
struct T1 { X a[2]; };
struct T2 { Y b[2]; };
union U { T1 t1; T2 t2; };
int f() {
  U u = {{{{0}, {1}}}}; // active member is t1
  return u.t2.b[1].y; // OK, as if the operand were u.t1.a[1].x
}
— end example]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions