www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - why is `typeid` only half baked?

reply Or Dahan <mailordahan gmail.com> writes:
When it comes to interfaces, apparently `typeid` always returns 
the type of the interface, An undocumented features, which is 
very misleading as for classes it returns the 'most derived type' 
(http://dlang.org/expression.html#TypeidExpression)

For example:

import std.stdio;

interface A {

}

class B : A {
     int y;
}

void foo(A a) {
     writefln("foo got 'a' of typeid(%s) which is really '%s'", 
typeid(a), a);
}

void main() {
     auto b = new B();
     writefln("Original scope got 'b' of typeid(%s) which is 
really '%s'", typeid(b), b);
     foo(b);
}

would print:

Original scope got 'b' of typeid(test.B) which is really 'test.B'
foo got 'a' of typeid(test.A) which is really 'test.B'

(notice that '%s' in the format correctly identifies 'a' to be of 
type 'B' in the same time that the typeid expression recognizes 
'a' as of type 'A')

Rewriting foo as:

void foo(A a) {
     writefln("foo got 'a' of typeid(%s) which is really '%s'", 
typeid(cast(Object)a), a);
}

solves the issue (Thanks to David Nadlinger)

I must say I find this very counter-intuitive as its VERY LIKELY 
to have an interface as the polymorphic instance and sometimes 
you would want to query its exact type.

Obviously `typeid` can infer that 'a' is really an `Object` and 
then infer that its of type `B` (just as the writefln managed to).
This leads me the conclusion that `typeid` is only half-baked and 
can be improved to support interfaces in a more intuitive manner.

Any reasons why it inherently can't be improved to do so?

Thanks.
Nov 06 2015
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote:
 Any reasons why it inherently can't be improved to do so?
You know, I was about to say no because interfaces can be objects from other languages... but the compiler is strict enough now that it can statically determine if that might be the case. If the interface derives from IUnknown, it might be a COM object so it can't be sure it is a D class. Similarly if it derives from extern(C++). In those cases, the cast to Object returns null, and attempting to get typeid() off it is liable to outright crash. But if it is a D interface... it should be ok doing an automatic cast to Object and trying to get typeinfo there. The only problem it might have is if the typeinfo is in a dll. But I think that has been basically solved too.
Nov 06 2015
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2015-11-06 18:03, Adam D. Ruppe wrote:
 On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote:
 Any reasons why it inherently can't be improved to do so?
You know, I was about to say no because interfaces can be objects from other languages... but the compiler is strict enough now that it can statically determine if that might be the case. If the interface derives from IUnknown, it might be a COM object so it can't be sure it is a D class. Similarly if it derives from extern(C++). In those cases, the cast to Object returns null, and attempting to get typeid() off it is liable to outright crash. But if it is a D interface... it should be ok doing an automatic cast to Object and trying to get typeinfo there. The only problem it might have is if the typeinfo is in a dll. But I think that has been basically solved too.
I had the same problem with "classinfo" [1], I guess that's basically the same as "typeid". The difference is that "classinfo" is specified in the spec that it will given information about the interface and not the class it might be an instance of [2]. [1] http://forum.dlang.org/post/mrl1uv$9ag$1 digitalmars.com [2] http://dlang.org/property.html#classinfo -- /Jacob Carlborg
Nov 06 2015
prev sibling parent reply Or Dahan <mailordahan gmail.com> writes:
On Friday, 6 November 2015 at 17:03:38 UTC, Adam D. Ruppe wrote:
 On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote:
 [...]
You know, I was about to say no because interfaces can be objects from other languages... but the compiler is strict enough now that it can statically determine if that might be the case. If the interface derives from IUnknown, it might be a COM object so it can't be sure it is a D class. Similarly if it derives from extern(C++). In those cases, the cast to Object returns null, and attempting to get typeid() off it is liable to outright crash. But if it is a D interface... it should be ok doing an automatic cast to Object and trying to get typeinfo there. The only problem it might have is if the typeinfo is in a dll. But I think that has been basically solved too.
So, is it planned to be changed?
Nov 09 2015
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Monday, 9 November 2015 at 10:22:09 UTC, Or Dahan wrote:
 So, is it planned to be changed?
I don't know, but I don't think so.
Nov 09 2015