Watcom C++ and vtbl pointers

What causes WCC to ad a vtbl pointer to a C++ class?
Is it as soon as you use the virtual qualifier at any point in the inheritance
tree?
Is it possible to keep virtual destructors and not have a vtbl pointer?

I’m passing some objects around in messages, virtual function table pointers
don’t work so well when they’re accessed in a new address space.
Is there any way to force a class to not use a vtbl ptr?

Thanks, Bruce.

You can’t have your cake and eat it too! Virtual functions
are implemented using vtbls… I usually just define a structure
used for transport, and then construct local objects out of that
structure should I need a more complex object.

I think “Advanced C++ Programming Styles and Idioms”, by Coplien,
had some funky ways of reconstructing vtbls using explicit calls
to the constructor, but funky is something best avoided in production
code. Still, it makes interesting reading.

Sam

Previously, Bruce Edge wrote in qdn.public.qnx4:

What causes WCC to ad a vtbl pointer to a C++ class?
Is it as soon as you use the virtual qualifier at any point in the inheritance
tree?
Is it possible to keep virtual destructors and not have a vtbl pointer?

I’m passing some objects around in messages, virtual function table pointers
don’t work so well when they’re accessed in a new address space.
Is there any way to force a class to not use a vtbl ptr?

Thanks, Bruce.


Sam Roberts (sam@cogent.ca), Cogent Real-Time Systems (www.cogent.ca)

Yes, I know in hindsight this was a bad design decision. Assuming that one can
control the memory layout of a C++ class is either arrogant or ignorant,
depending on one’s level of experience :slight_smile:

Turns out, someone had made the base class destructor virtual. This is what
had caused the vtbl pointer to get added to the class.

A last philosophical question, and a chance to flaunt my C++ ignorance, why
would you want destructor to be virtual?

-Bruce.

Sam Roberts wrote:

You can’t have your cake and eat it too! Virtual functions
are implemented using vtbls… I usually just define a structure
used for transport, and then construct local objects out of that
structure should I need a more complex object.

I think “Advanced C++ Programming Styles and Idioms”, by Coplien,
had some funky ways of reconstructing vtbls using explicit calls
to the constructor, but funky is something best avoided in production
code. Still, it makes interesting reading.

Sam

Previously, Bruce Edge wrote in qdn.public.qnx4:
What causes WCC to ad a vtbl pointer to a C++ class?
Is it as soon as you use the virtual qualifier at any point in the inheritance
tree?
Is it possible to keep virtual destructors and not have a vtbl pointer?

I’m passing some objects around in messages, virtual function table pointers
don’t work so well when they’re accessed in a new address space.
Is there any way to force a class to not use a vtbl ptr?

Thanks, Bruce.

\

Sam Roberts (> sam@cogent.ca> ), Cogent Real-Time Systems (> www.cogent.ca> )

In article <39AD3400.72FDEA87@sattel.com>,
Bruce Edge <bedge@sattel.com> wrote:

Yes, I know in hindsight this was a bad design decision. Assuming that one can
control the memory layout of a C++ class is either arrogant or ignorant,
depending on one’s level of experience > :slight_smile:

Turns out, someone had made the base class destructor virtual. This is what
had caused the vtbl pointer to get added to the class.

A last philosophical question, and a chance to flaunt my C++ ignorance, why
would you want destructor to be virtual?

For heterogeneous collections and the like.

If you place an object in a collection of, say, Shapes and the collection
becomes responsible for managing the lifetime of the objects, it will
be important for a delete of the object to invoke the correct
destructor for the actual derived class.

Think in particular of a class that uses zoned allocation. The destructor
will have to put the memory back in the correct zone. Also any owned
fields will have to be released.

e.g.

class Shape {
public:
void draw() {
}

virtual ~Shape() {
}
}

class WidgetShape {
public:
PtWidget_t *widget;

WidgetShape() {
widget = PtCreateWidget(…);
}

virtual ~WidgetShape() {
PtDestroyWidget(widget);
}
}

If a collection of Shape deleted a WidgetShape, the Widget would stick
around if the destructor weren’t virtual, as Shape::~Shape would be
called instead of WidgetShape::~WidgetShape.


Steve Furr email: furr@qnx.com
QNX Software Systems, Ltd.

Was WidgetShape supposed to be:
class WidgetShape : public Shape {…

That makes sense. Thank you for the detailed answer.

-Bruce.


Steve Furr wrote:

In article <> 39AD3400.72FDEA87@sattel.com> >,
Bruce Edge <> bedge@sattel.com> > wrote:
Yes, I know in hindsight this was a bad design decision. Assuming that one can
control the memory layout of a C++ class is either arrogant or ignorant,
depending on one’s level of experience > :slight_smile:

Turns out, someone had made the base class destructor virtual. This is what
had caused the vtbl pointer to get added to the class.

A last philosophical question, and a chance to flaunt my C++ ignorance, why
would you want destructor to be virtual?

For heterogeneous collections and the like.

If you place an object in a collection of, say, Shapes and the collection
becomes responsible for managing the lifetime of the objects, it will
be important for a delete of the object to invoke the correct
destructor for the actual derived class.

Think in particular of a class that uses zoned allocation. The destructor
will have to put the memory back in the correct zone. Also any owned
fields will have to be released.

e.g.

class Shape {
public:
void draw() {
}

virtual ~Shape() {
}
}

class WidgetShape {
public:
PtWidget_t *widget;

WidgetShape() {
widget = PtCreateWidget(…);
}

virtual ~WidgetShape() {
PtDestroyWidget(widget);
}
}

If a collection of Shape deleted a WidgetShape, the Widget would stick
around if the destructor weren’t virtual, as Shape::~Shape would be
called instead of WidgetShape::~WidgetShape.


Steve Furr email: > furr@qnx.com
QNX Software Systems, Ltd.