why is `typeid` only half baked?

Steven Schveighoffer schveiguy at yahoo.com
Sat Jun 30 12:18:51 UTC 2018


On 6/30/18 7:30 AM, Mr.Bingo wrote:
> 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.

You are answering a nearly 3-year-old thread. I don't know if he cares 
any more ;)

-Steve


More information about the Digitalmars-d mailing list