Bill Baxter wrote: > On Tue, Nov 24, 2009 at 3:09 PM, Saaa <em...@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.