why is `typeid` only half baked?

Mr.Bingo Bingo at Namo.com
Sat Jun 30 11:30:58 UTC 2018


On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote:
> 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.

Maybe this is because the compiler is computing the typeid at 
runtime? This is because a is of type A! It's clearly stated in 
the signature:


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

typeid(a) looks at the type of a and see's A and hence that is 
what it is "locally"(it mistakenly evaluates typeid because it 
does not realize that a could be any B : A).

If typeid(cast(Object)a) produces a different result then clearly 
dmd is doing something wrong.







More information about the Digitalmars-d mailing list