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