Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[class.prop]/(3.7) is in contradiction with [class.prop]/(3.7.3) #4217

Closed
JoaoAfonso1 opened this issue Sep 21, 2020 · 1 comment
Closed

Comments

@JoaoAfonso1
Copy link

[class.prop]/(3.7):

  • has no element of the set M(S) of types as a base class, where for any type X, M(X) is defined as follows.104 [Note 2: M(X) is the set of the types of all non-base-class subobjects that may be at a zero offset in X. — end note]

[class.prop]/(3.7.3):

  • If X is a union type, the set M(X) is the union of all M(Ui) and the set containing all Ui, where each Ui is the type of the ith non-static data member of X.

The contradiction comes from the fact that a union doesn't have base classes (see this sentence in [class.union]/4). Thus, from the sentence highlighted above in [class.prop]/(3.7), the set M(S) is empty when S is a union, which proves the contradiction with [class.prop]/(3.7.3).

I know that this is not an editorial issue, but the solution is so simple that I decided to give it a try:

[class.prop]/(3.7.3) can simply be eliminated from [class.prop]/(3.7) for the following reason: a union U is a non-standard-layout class if any non-static subobject of class type inside U is non-standard-layout, and this will be caught by paragraph (3.1) , which says:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,

Otherwise, i.e., if every non-static subobject of class type inside U is a standard-layout class, U is a standard-layout class.

One other solution would be to replace [class.prop]/(3.7.3) with:

  • If X is a union type, the set M(X) is empty.
@zygoloid
Copy link
Member

The wording is correct as-is. Consider:

struct A {};
union U { A a; };
struct B : A { U u; };

Here, B is not standard-layout because M(B) contains A and B has A as a base class. M(B) is defined as U plus M(U), and M(U) is defined as A.

So we need M(U) to be non-empty for M(B) to properly compute "the set of the types of all non-base-class subobjects that may be at a zero offset in" U, even though U itself can't have base class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants