digitalmars.D - why is `typeid` only half baked?
- Or Dahan (42/42) Nov 06 2015 When it comes to interfaces, apparently `typeid` always returns
- Adam D. Ruppe (12/13) Nov 06 2015 You know, I was about to say no because interfaces can be objects
- Jacob Carlborg (9/22) Nov 06 2015 I had the same problem with "classinfo" [1], I guess that's basically
- Or Dahan (2/17) Nov 09 2015 So, is it planned to be changed?
- Adam D. Ruppe (2/3) Nov 09 2015 I don't know, but I don't think so.
- Mr.Bingo (14/59) Jun 30 2018 Maybe this is because the compiler is computing the typeid at
- Steven Schveighoffer (4/81) Jun 30 2018 You are answering a nearly 3-year-old thread. I don't know if he cares
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
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
On 2015-11-06 18:03, Adam D. Ruppe wrote:On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote: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 CarlborgAny 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
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:So, is it planned to be changed?[...]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 09 2015
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
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.
Jun 30 2018
On 6/30/18 7:30 AM, Mr.Bingo wrote:On Friday, 6 November 2015 at 16:38:04 UTC, Or Dahan wrote:You are answering a nearly 3-year-old thread. I don't know if he cares any more ;) -SteveWhen 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.
Jun 30 2018