C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Idea: extend forward declarations to include base class(s)
From: Tony V E (tvaneerd_at_[hidden])
Date: 2020-02-22 17:01:44


Eventually all syntax will be valid syntax.

Sent from my BlackBerry portable Babbage Device
From: Arthur O'Dwyer via Std-Proposals
Sent: Saturday, February 22, 2020 5:52 PM
To: sotrdg sotrdg via Std-Proposals
Reply To: std-proposals@lists.isocpp.org
Cc: Arthur O'Dwyer
Subject: Re: [std-proposals] Idea: extend forward declarations to include base class(s)

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@lists.isocpp.org> 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@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals


STD-PROPOSALS list run by herb.sutter at gmail.com

Standard Proposals Archives on Google Groups