Date: Wed, 10 May 2023 22:22:10 +0100
On Wed, 2023-05-10 at 05:43 -0500, Edward Catmur wrote:
>
>
> On Tue, May 9, 2023, 17:18 Lénárd Szolnoki via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> > Hi,
> >
> > Consider the following code:
> >
> > #include <type_traits>
> >
> > struct A {};
> > struct B : A { char ch; };
> >
> > struct C : A {
> > B b;
> > };
> >
> > static_assert(std::is_standard_layout_v<C>);
> > static_assert(sizeof(C) == 2);
> >
> > In my reading of https://eel.is/c++draft/class.prop#3 C is
> > standard-
> > layout. GCC with libstdc++ agrees.
> >
> > However the offset of a `b` subobject within an object of C is 1
> > instead of 0 as compiled by both gcc and clang, making it
> > definitely
> > not pointer-interconvertible with the parent object, even though
> > it's
> > required to be:
> >
> > https://eel.is/c++draft/basic.compound#4.3
> >
> > Note that there are two subobjects of type A, requiring different
> > addresses, which makes implementing this tricky, if not impossible.
> >
> > Anyway, https://eel.is/c++draft/class.prop#note-2 suggests that Cis
> > not
> > intended to be standard-layout, however C satisfies the
> > corresponding
> > normative wording https://eel.is/c++draft/class.prop#3.7:
> >
> > * M(C): https://eel.is/c++draft/class.prop#3.7.2 applies, M(C) is
> > the
> > union of {B} and M(B)
> > * M(B) same applies, M(B) is union of {char} and M(char)
> > * M(char): empty https://eel.is/c++draft/class.prop#3.7.5
> >
> > Therefore M(C) is {B, char}, none of which is a base of C.
> >
> > Is this a defect, or did I make a mistake somewhere in my
> > reasoning?
>
> Yes, this looks new. We got the current wording in
> https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1672
> but see
> also https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#18
> 13
>
> TBH, it looks like this has been broken since C++11 (when we first
> allowed standard layout class types to have bases).
> https://timsong-cpp.github.io/cppwp/n3337/class#7
>
> Fixing it will be slightly tricky; it's only the early (zero-offset)
> bases of the first data member that (need to) conflict. What do clang
> and msvc do in that case?
>
> Do you want to file via https://github.com/cplusplus/CWG/issues ?
I created https://github.com/cplusplus/CWG/issues/317 .
>
> >
> > Cheers,
> > Lénárd
>
>
> On Tue, May 9, 2023, 17:18 Lénárd Szolnoki via Std-Discussion
> <std-discussion_at_[hidden]> wrote:
> > Hi,
> >
> > Consider the following code:
> >
> > #include <type_traits>
> >
> > struct A {};
> > struct B : A { char ch; };
> >
> > struct C : A {
> > B b;
> > };
> >
> > static_assert(std::is_standard_layout_v<C>);
> > static_assert(sizeof(C) == 2);
> >
> > In my reading of https://eel.is/c++draft/class.prop#3 C is
> > standard-
> > layout. GCC with libstdc++ agrees.
> >
> > However the offset of a `b` subobject within an object of C is 1
> > instead of 0 as compiled by both gcc and clang, making it
> > definitely
> > not pointer-interconvertible with the parent object, even though
> > it's
> > required to be:
> >
> > https://eel.is/c++draft/basic.compound#4.3
> >
> > Note that there are two subobjects of type A, requiring different
> > addresses, which makes implementing this tricky, if not impossible.
> >
> > Anyway, https://eel.is/c++draft/class.prop#note-2 suggests that Cis
> > not
> > intended to be standard-layout, however C satisfies the
> > corresponding
> > normative wording https://eel.is/c++draft/class.prop#3.7:
> >
> > * M(C): https://eel.is/c++draft/class.prop#3.7.2 applies, M(C) is
> > the
> > union of {B} and M(B)
> > * M(B) same applies, M(B) is union of {char} and M(char)
> > * M(char): empty https://eel.is/c++draft/class.prop#3.7.5
> >
> > Therefore M(C) is {B, char}, none of which is a base of C.
> >
> > Is this a defect, or did I make a mistake somewhere in my
> > reasoning?
>
> Yes, this looks new. We got the current wording in
> https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1672
> but see
> also https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#18
> 13
>
> TBH, it looks like this has been broken since C++11 (when we first
> allowed standard layout class types to have bases).
> https://timsong-cpp.github.io/cppwp/n3337/class#7
>
> Fixing it will be slightly tricky; it's only the early (zero-offset)
> bases of the first data member that (need to) conflict. What do clang
> and msvc do in that case?
>
> Do you want to file via https://github.com/cplusplus/CWG/issues ?
I created https://github.com/cplusplus/CWG/issues/317 .
>
> >
> > Cheers,
> > Lénárd
Received on 2023-05-10 21:22:15