Date: Tue, 09 May 2023 23:18:09 +0100
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?
Cheers,
Lénárd
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?
Cheers,
Lénárd
Received on 2023-05-09 22:18:16