Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 02, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 Kenji Hara <k.hara.pg@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |pull --- Comment #1 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Kenji Hara from comment #0) > 2. Separate ClassInfo from TypeInfo_Class again and define TypeInfo hierarchy as follows: > > abstract class ClassInfo : TypeInfo { ... } > class TypeInfo_Class : ClassInfo { ... } > class TypeInfo_Interface : ClassInfo { ... } > > Pros: By handling ClassInfo, the runtime cost in dynamic cast operation can > be kept same with today's. > Cons: If an user still using the name 'ClassInfo', the code behavior will be > changed. Implemented: https://github.com/D-Programming-Language/dmd/pull/4711 https://github.com/D-Programming-Language/druntime/pull/1295 -- |
July 05, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 Rainer Schuetze <r.sagitario@gmx.de> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |r.sagitario@gmx.de --- Comment #2 from Rainer Schuetze <r.sagitario@gmx.de> --- The language spec says for both typeid() and .classinfo that the dynamic type is returned. For classinfo, it says ".classinfo applied to an interface gives the information for the interface, not the class it might be an instance of." which makes it a compile time property for interfaces. I could not find a spec for typeid regarding interfaces. I suspect they are supposed to be the same. That means typeid(i) and i.classinfo should evaluate to typeid(I). This must be generated by the compiler. Actually I think the semantics are pretty arbitrary and not intuitive. Why would anyone expect J to be the correct type? I'd rather prefer if both classes and interfaces would return the dynamic type, i.e. typeid(D). You can get the static type of an expression by using typeid(typeof(i)). -- |
July 09, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #3 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Rainer Schuetze from comment #2) > The language spec says for both typeid() and .classinfo that the dynamic type is returned. For classinfo, it says ".classinfo applied to an interface gives the information for the interface, not the class it might be an instance of." which makes it a compile time property for interfaces. I could not find a spec for typeid regarding interfaces. > > I suspect they are supposed to be the same. That means typeid(i) and > i.classinfo should evaluate to typeid(I). This must be generated by the > compiler. It's correct. typeid(obj) and obj.classinfo are just same thing in implementation level. > Actually I think the semantics are pretty arbitrary and not intuitive. Why > would anyone expect J to be the correct type? I'd rather prefer if both > classes and interfaces would return the dynamic type, i.e. typeid(D). You > can get the static type of an expression by using typeid(typeof(i)). I don't know why so, but I guess it might be the dynamic cast cost. The current behavior, getting actual interface information (== classinfo) can be done with a trivial pointer (== class/interface reference) adjustment. On the other hand, a dynamic cast from interface to class needs more cost. 1. getting the interface information 2. downcast and get Object reference from the interface reference by using the information. 3. get the actual typeinfo from the Object reference. And you can do the latter behavior by typeid(cast(Object)obj). I feel that syntactic cost is enough small. In short, the orthogonality may have been priority than the intuitive, but complex behavior. -- |
July 10, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #4 from Rainer Schuetze <r.sagitario@gmx.de> --- > And you can do the latter behavior by typeid(cast(Object)obj). > I feel that syntactic cost is enough small. cast(Object) creates a call into the runtime (_d_interface_cast) and is pretty expensive. It could be optimized to the series of indirections by the compiler, though. > In short, the orthogonality may have been priority than the intuitive, but complex behavior. The "complex" behaviour costs just an additional reading of an offset to the object base address, very much what a thunk does when calling a virtual function. I guess the current behaviour could be described as "typeid(I) evaluates to the most derived interface that is implemented by the object and that inherits from the static type." But "most derived" is not well defined when it comes to inheriting from multiple interfaces: import std.stdio; interface I {} interface J : I {} interface K : I {} class E : J, K {} void main() { E e = new E; J j = e; K k = e; I ij = j; I ik = k; writeln(typeid(ij)); // prints 'test.J' !? writeln(typeid(ik)); // prints 'test.K' !? } -- |
July 21, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #5 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Rainer Schuetze from comment #4) > cast(Object) creates a call into the runtime (_d_interface_cast) and is > pretty expensive. It could be optimized to the series of indirections by the > compiler, though. Actually _d_interface_cast is not so high cost so Object has no base class and implements no interfaces. > I guess the current behaviour could be described as "typeid(I) evaluates to the most derived interface that is implemented by the object and that inherits from the static type." > > But "most derived" is not well defined when it comes to inheriting from multiple interfaces: It would be visible when you consider the class object layout. > interface I {} > interface J : I {} > interface K : I {} > class E : J, K {} // I I // E : J, K //=============== // ij ik // | | // j k // | | // e --[x]-[y] [x] is the "most derived vptr slot of ij, and [y] is of ik. -- |
July 21, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #6 from Kenji Hara <k.hara.pg@gmail.com> --- Anyway, the downcast behavior is not a part of the suggested issue. It should go an enhancement report. -- |
July 21, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #7 from Kenji Hara <k.hara.pg@gmail.com> --- (In reply to Rainer Schuetze from comment #4) > But "most derived" is not well defined when it comes to inheriting from multiple interfaces: I found an existing report: Issue 13833 - .classinfo.name (and typeid(obj)) does not print proper dynamic type when using an interface -- |
July 22, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #8 from Rainer Schuetze <r.sagitario@gmx.de> --- > Actually _d_interface_cast is not so high cost so Object has no base class and implements no interfaces. It's still a lot more than just a null check and reading a vtbl entry an another indirection. If the instance is from a deeply derived class, _d_interface_cast walks through all base classes to find Object. -- |
July 22, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #9 from Rainer Schuetze <r.sagitario@gmx.de> --- > [x] is the "most derived vptr slot of ij, and [y] is of ik. But if all you have is a pointer to I that's not very deterministic. -- |
August 03, 2015 [Issue 14612] typeid(interface) returns TypeInfo_Class object | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=14612 --- Comment #10 from Kenji Hara <k.hara.pg@gmail.com> --- I found slightly related issue tickets: Issue 4979 - Implementing an interface twice results in different a reference for each interface Issue 11683 - Document current Identity Expression over `interface`s behaviour -- |
Copyright © 1999-2021 by the D Language Foundation