why can't structs implement interfaces?

Daniel Keep daniel.keep.lists at gmail.com
Tue Nov 24 16:38:15 PST 2009



Bill Baxter wrote:
> On Tue, Nov 24, 2009 at 3:09 PM, Saaa <empty at needmail.com> wrote:
> 
>>>> I wanted to do something like this:
>>>>
>>>> class C : I {};
>>>> struct S : I {};
>>>> S s;
>>>> I[] i =[new C(), s ];
>>> Yeh, that's never going to work because that's acting as a dynamic
>>> polymorphic interaface.  Referring polymorphically to a struct like
>>> that pretty much makes it not a struct anymore, and requires having
>>> the hidden pointer to a vtable that was mentioned.  That's what
>>> classes are for.
>> Why is a hidden pointer necessary? (Just curious :)
>>
>> My simplistic view was like this:
>> i[1] would just hold the location of s and s would be checked to have
>> all it needs to be an I.
> 
> I think it could be done with a different implementation of interfaces
> from the one D uses, one based on "fat pointers".
> With that design an I referring to an S would be a "fat pointer", one
> pointer pointing to the S and one pointing to S's table of function
> pointers (vtable) for the I interface.
> 
> That's not how D does it AFAIR, but I don't actually recall how D does it.
> 
> --bb

(This is all off the top of my head.)

In D, interfaces are pointers to the vtable which implements the
interface for a particular class.  In order to actually get the "this"
reference, D stores a pointer to the class' InterfaceInfo (or something)
for that interface in the first slot of the vtable.

This InterfaceInfo indicates how far from the start of an instance the
pointer to the vtable is contained.  To get "this", you take the pointer
to the interface vtable and subtract this offset.

This is why interfaces cannot be implemented by structs in D: it would
require structs to grow magical hidden fields, which is explicitly
against the stated purpose of structs: plain old data.

Even then, there's a worse problem.  All interfaces can be cast to
Object, and then upcast to any valid class.  This is done via the use of
the first slot of the object's vtable, which contains the ClassInfo.

But if you allow structs as interfaces, you're suddenly in the position
where you might not actually have an object at all.  If you tried to
cast a struct to an Object, it might not actually fail; if you're lucky,
you'll get a segfault.

The only solution there is to give structs a vtable.  At which point,
congratulations, you've just re-invented classes.

To allow structs to implement interfaces would require redesigning how
interfaces are actually implemented.  You'd probably have to also
redesign RTTI as well, object casting, etc.


More information about the Digitalmars-d-learn mailing list