[class.mem.general] Fix wording regarding layout-compatible types#8787
[class.mem.general] Fix wording regarding layout-compatible types#8787Halalaluyafail3 wants to merge 1 commit intocplusplus:mainfrom
Conversation
It would not make sense if a non-union class having member functions or static data members would stop it from being layout-compatible with other types.
|
It seems like the layout-compatibility of C and D, as well as K and L can be explained by "same alignment requirements" in the definition of common initial sequence including the alignment of the types themselves. Though that creates new issues: struct O{char x;};
struct alignas(2)P{char x;};
struct Q{A y;int z;};
struct R{B y;int z;};
static_assert(alignof(int)>1);Does the declaration of the later z members in both Q and R cause the alignment requirements of each y member to be greater than one as a result? Because of pointer-interconvertibility the y members must have the same alignments as their respective containing classes. If yes, then Q and R are layout-compatible. Otherwise, Q and R are not layout-compatible. |
|
I'll be glad if some fixes can be considered editorial.
This seems to be an unintended bug in the wording update of CWG1719.
Looks like an oversight in #700 to me. I believe layout-compatible unions should also be layout-compatible classes. CC @AaronBallman @zygoloid. For Remaining questions will require CWG issues, IMO. For |
|
There's nothing editorial here. |
|
I think the status quo for Consider this more realistic example, where the tail padding of // tail-padded in common implementations, made non-POD due to weirdness of Itanium ABI
struct Padded { int n{}; char c{}; };
union G2 { Padded x; };
union H2 { [[no_unique_address]] Padded x; };In order to reuse the padding of When there's no outer |
Status quo of the wording, or status quo of the existing implementations? Both GCC and Clang reject that G and H are layout-compatible, MSVC of course accepts it since it ignores no_unique_address.
As far as I understand, tail padding like this cannot be used by used later by other non-empty objects: https://eel.is/c++draft/intro.object#10. For example: //same Padded as before
struct S{[[no_unique_address]]Padded x;char y;};For the members x and y to overlap in storage, one of the following conditions must be followed: "one is nested within the other", "at least one is a subobject of zero size and they are not of similar types", or "they are both potentially non-unique objects". x and y are obviously not nested within the other member. An object of type S can obviously be created that is not potentially non-unique. y does not have zero size because it is not a class type. x does not have zero size because it contains subobjects of non-zero size. Therefore x and y cannot overlap in storage, and Itanium letting them overlap seems more like an ABI bug. |
|
I don't think Having two unions with different alignment requirements doesn't seem to cause layout difference for the union itself: If you put those in a "common initial sequence" situation, those are not layout-compatible at that level, because the unions themselves have different alignment requirements (indirectly caused by different alignment requirements of their members). I agree that bit-field lengths need to be compared for layout compatibility of union members. |
struct T{int x;char c{};};
union U{int y;[[no_unique_address]]T t;};
struct V{[[no_unique_address]]U u;char z;};With Itanium the size of V changes depending upon whether or not the member t of T is declared with no_unique_address. |
The current wording doesn't restrict conditions for "overlapping" the whole members in that way. For such IIUC, given such an
I believe this is conforming.
I think the status quo of the wording (in the case of |
This part I think the standard does not state very clearly, I created cplusplus/CWG#868 for that.
I suppose it does not really matter because for no_unique_address on the members of a union to matter, the union which contains it must be part of a non-union class (possibly as a submember) and no_unique_address is used on the member which is the union or contains the union. In which case the use of no_unique_address would prevent layout-compatibility. I do not see the use case for it though, I think CWG should decide what is the intent here. |
|
I've come around to agreeing that [[no_unique_address]] on union members has an effect, at least for the "re-use tail padding" examples posted here. |
According to the current wording:
These types are not layout-compatible because the member function is not included in the common initial sequence. Moreover, even if A had the same member function it would not be included in the common initial sequence so B cannot be layout-compatible with any other type. There are more related issues:
The current wording for layout-compatible unions does not mention alignment, so the current wording says these types are layout-compatible even though they clearly ought not to be.
The current wording for layout-compatible unions does not mention bit-field widths, so the current wording says these types are layout-compatible even though they clearly ought not to be.
The current wording for layout-compatible unions does not mention no_unique_address, so the current wording says these types are layout-compatible even though they clearly ought not to be if no_unique_address is supported.
The current wording for layout-compatible unions does not mention unnamed bit-fields as they are not members, so the current wording says these types are layout-compatible even though they clearly ought not to be.
The current wording for layout-compatible classes and layout-compatible unions (layout-compatible unions are not layout-compatible classes, despite being classes and layout-compatible) does not mention alignas applied to the type, so the current wording says these types are layout-compatible even though they clearly ought not to be.
The current wording does not clearly define what "same alignment requirements" means, there is some compiler divergence here about whether or not these types are layout-compatible.
I have only proposed changes to the first issue since it seems the most clear and requires only a small change to fix. If any of the other issues listed here could be fixed editorially too, I would be willing to include fixes for them too.