toHash() and Interfaces

Steven Schveighoffer schveiguy at yahoo.com
Mon May 16 07:21:39 PDT 2011


On Wed, 11 May 2011 19:43:03 -0400, Stewart Gordon <smjg_1998 at yahoo.com>  
wrote:

> On 06/05/2011 13:02, Steven Schveighoffer wrote:
> <snip>
>> D has this horrible notion that any interface can be for a COM object,  
>> even though COM
>> interfaces can only inherit from IUnknown (known statically).  
>> Therefore, interfaces that
>> don't inherit from IUnknown are not considered Objects, even though  
>> they could and should be.
>
> Firstly, IUnknown is defined in the Phobos files, not a language  
> built-in.  There might be multiple IUnknowns, defined in different  
> modules (e.g. because some set of bindings has its own copy).  How  
> should the compiler identify the IUnknown to use?  By name?  By the  
> signatures of functions specified within it?  By fully qualified name?

No, the compiler treats it specially, COM interfaces and classes have a  
different layout than D objects, so the compiler has to generate different  
code if the class implements an interface which inherits from  
std.c.windows.com.IUnknown.

 From the spec:

A COM interface is defined as one that derives from the interface  
std.c.windows.com.IUnknown. A COM interface differs from a regular D  
interface in that:

* It derives from the interface std.c.windows.com.IUnknown.
* It cannot be the argument of a DeleteExpression.
* References cannot be upcast to the enclosing class object, nor can they  
be downcast to a derived interface. To accomplish this, an appropriate  
QueryInterface() would have to be implemented for that interface in  
standard COM fashion.
* Classes derived from COM interfaces are COM classes.
* The default linkage for member functions of COM classes is  
extern(System).
* The first member of the vtbl[] is not the pointer to the InterfaceInfo,  
but the first virtual function pointer.


----------------

There is nothing here that makes it seem like this is undetectable at  
compile time.

IMO:
* cast(Object)someComInterface => compiler error
* Object o = someComInterface => compiler error
* Object o = someNormalInterface => success

Is all doable without incurring any problems.

> Secondly, I guess it's perfectly possible for some other system, besides  
> COM, to create non-D objects that implement D interfaces.

But none of these exist today.  All cases of 'alternative' interfaces have  
alternative layouts and statically detectable triggers (such as IUnknown)  
that would allow us to statically allow or disallow implicit casting to  
Object.  If we simply make a rule right now that alternative layouts have  
to be typed with some modifier (like extern(C++) for example) we can have  
implicit casting to object and get rid of all these ridiculous problems.

>> So you have to manually cast an interface to Object in order to call an  
>> Object function.
>
> Which you can do, if you are certain that the object will always be a D  
> object.  I guess the whole point is to protect you from those cases  
> where you can't be sure.

The compiler can always be sure, it just isn't programmed to know it yet...

-Steve


More information about the Digitalmars-d-learn mailing list