Date: Sat, 22 Feb 2020 17:51:45 -0500
Correct, the vptr always comes first (in Itanium ABI). This means that if
you have a (void*) that "I don't know what it points at, but I know that
whatever it points at is polymorphic," then you can get to the
std::type_info of that mystery object via a known recipe.
Here is a simple illustration of Thiago's point:
https://godbolt.org/z/AHWREH
Without knowing the definition of `B`, the compiler cannot know whether a
conversion from `D*` to `B*` requires an adjustment.
Without knowing the definition of `D`, the compiler cannot know whether a
conversion from `D*` to `B*` requires an adjustment.
Incidentally, John, it occurs to me that C++ already assigns a meaning to
struct D B;
struct D B, C;
and that this might possibly be a (weak) reason not to add meanings for
struct D: B;
struct D: B, C;
because of the risk of visual confusion, and possibly even wrong intuition
as to what `struct D: B, C;` is supposed to mean. (Basically, does `,` bind
tighter than `:`? You definitely want it to, but is this intuitively
obvious to the uninitiated programmer?)
However, I readily admit that historically C++ has never let "fear of line
noise" stand in the way of even the tiniest convenience feature.
HTH,
Arthur
On Sat, Feb 22, 2020 at 4:37 PM Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Saturday, 22 February 2020 12:49:36 PST John Yates via Std-Proposals
> wrote:
> > To me a forward declaration of either of those structs as simply struct
> D:
> > B;
> > is clearly an error. When forward declaring base classes any failure to
> > match exactly the actual declaration (number, order, virtualness, etc.)
> > should at the very least be UB.
>
> That would be implied, yes.
>
> Just to confirm without multiple or virtual inheritance:
>
> struct B;
> struct D : B;
>
> /* later */
>
> struct B { int i; };
> struct D : B
> {
> virtual ~D();
> };
>
> What is the layout of D? Two options will apply for 99% of the ABIs
> (64-bit
> here):
>
> 0 4 8 12 16
> +-----+-----+-----+------+
> | i | pad | vtable |
> +-----+-----+-----+------+
>
> or
>
> 0 4 8 12 16
> +-----+-----+-----+------+
> | vtable | i | pad |
> +-----+-----+-----+------+
>
> In the first scenario, D and B share top-of-object address. I thought the
> first case would be what the IA-64 ABI would do. But a quick test at
> https://gcc.godbolt.org/z/R5FLkF shows that it is in fact the second
> case, as
> you can see from:
> movq $_ZTV1D+16, (%rax)
> movl $42, 8(%rax)
>
> Same for the MSVC ABI.
>
> That is, the B-in-D sub-object is not allocated at the top of the D object.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel System Software Products
>
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
you have a (void*) that "I don't know what it points at, but I know that
whatever it points at is polymorphic," then you can get to the
std::type_info of that mystery object via a known recipe.
Here is a simple illustration of Thiago's point:
https://godbolt.org/z/AHWREH
Without knowing the definition of `B`, the compiler cannot know whether a
conversion from `D*` to `B*` requires an adjustment.
Without knowing the definition of `D`, the compiler cannot know whether a
conversion from `D*` to `B*` requires an adjustment.
Incidentally, John, it occurs to me that C++ already assigns a meaning to
struct D B;
struct D B, C;
and that this might possibly be a (weak) reason not to add meanings for
struct D: B;
struct D: B, C;
because of the risk of visual confusion, and possibly even wrong intuition
as to what `struct D: B, C;` is supposed to mean. (Basically, does `,` bind
tighter than `:`? You definitely want it to, but is this intuitively
obvious to the uninitiated programmer?)
However, I readily admit that historically C++ has never let "fear of line
noise" stand in the way of even the tiniest convenience feature.
HTH,
Arthur
On Sat, Feb 22, 2020 at 4:37 PM Thiago Macieira via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> On Saturday, 22 February 2020 12:49:36 PST John Yates via Std-Proposals
> wrote:
> > To me a forward declaration of either of those structs as simply struct
> D:
> > B;
> > is clearly an error. When forward declaring base classes any failure to
> > match exactly the actual declaration (number, order, virtualness, etc.)
> > should at the very least be UB.
>
> That would be implied, yes.
>
> Just to confirm without multiple or virtual inheritance:
>
> struct B;
> struct D : B;
>
> /* later */
>
> struct B { int i; };
> struct D : B
> {
> virtual ~D();
> };
>
> What is the layout of D? Two options will apply for 99% of the ABIs
> (64-bit
> here):
>
> 0 4 8 12 16
> +-----+-----+-----+------+
> | i | pad | vtable |
> +-----+-----+-----+------+
>
> or
>
> 0 4 8 12 16
> +-----+-----+-----+------+
> | vtable | i | pad |
> +-----+-----+-----+------+
>
> In the first scenario, D and B share top-of-object address. I thought the
> first case would be what the IA-64 ABI would do. But a quick test at
> https://gcc.godbolt.org/z/R5FLkF shows that it is in fact the second
> case, as
> you can see from:
> movq $_ZTV1D+16, (%rax)
> movl $42, 8(%rax)
>
> Same for the MSVC ABI.
>
> That is, the B-in-D sub-object is not allocated at the top of the D object.
>
> --
> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
> Software Architect - Intel System Software Products
>
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2020-02-22 16:54:37