digitalmars.D - -betterC and extern(C++) classes
- Yuxuan Shui (7/7) Sep 10 2017 I was experimenting with -betterC and found out that C++ classes
- rikki cattermole (8/16) Sep 10 2017 Definitely not.
- 9il (7/21) Sep 10 2017 No. vtables can be generated without RTTI and we can have both D
- rikki cattermole (3/29) Sep 10 2017 Agreed, but that is a bigger change and would require a bit more of a
- Paulo Pinto (6/23) Sep 10 2017 You sure can do that in C++, since Windows 3.x days.
- Walter Bright (3/9) Sep 10 2017 Yes, we do want to move towards "Better C++" working in an analogous man...
- Adam D. Ruppe (4/7) Sep 10 2017 TypeInfo is cheap and useful with classes.
- Moritz Maxeiner (14/26) Sep 10 2017 If TypeInfo for extern(C++) classes is removed, couldn't final
- rikki cattermole (3/17) Sep 10 2017 We can do it for any class if its final. The problem isn't generating
- Moritz Maxeiner (12/32) Sep 10 2017 Even final classes can always inherit (potentially already
- Yuxuan Shui (5/38) Sep 10 2017 With a final class reference, we always know what function to
- Moritz Maxeiner (41/73) Sep 10 2017 ---
- Yuxuan Shui (2/14) Sep 10 2017 Is there a plan? Are there any simple tasks I can take/help?
- Walter Bright (4/5) Sep 10 2017 I filed an enhancement request:
- Yuxuan Shui (2/2) Sep 10 2017 By the way, can we dynamic_cast extern(C++) classes in C++? If
- Moritz Maxeiner (86/87) Sep 10 2017 It doesn't work for me OOTB with dmd 2.075, at least (though I
- Walter Bright (9/11) Sep 10 2017 No. Generally, one would need C++ RTTI for that to work, and that:
I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo? Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening? Thanks.
Sep 10 2017
On 10/09/2017 9:40 AM, Yuxuan Shui wrote:I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo?Nope.Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening? Thanks.Definitely not. Classes require vtable's to work. Vtables are generated as part of TypeInfo. No TypeInfo, no classes, simple to understand. Same reason why you can't use classes and cross the dll boundary on Windows. But if you prefer not having any methods to call, then I'm sure we can remove the requirement on the vtable ;) (Not a solution)
Sep 10 2017
On Sunday, 10 September 2017 at 08:56:11 UTC, rikki cattermole wrote:On 10/09/2017 9:40 AM, Yuxuan Shui wrote:No. vtables can be generated without RTTI and we can have both D and C++ classes in betterC mode. It may not be ready now, but it is definitely possible and should be supported. Best reagards, IlyaI was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo?Nope.Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening? Thanks.Definitely not. Classes require vtable's to work. Vtables are generated as part of TypeInfo. No TypeInfo, no classes, simple to understand.
Sep 10 2017
On 10/09/2017 10:03 AM, 9il wrote:On Sunday, 10 September 2017 at 08:56:11 UTC, rikki cattermole wrote:Agreed, but that is a bigger change and would require a bit more of a rethink than just a simple 'remove reference to symbol'.On 10/09/2017 9:40 AM, Yuxuan Shui wrote:No. vtables can be generated without RTTI and we can have both D and C++ classes in betterC mode. It may not be ready now, but it is definitely possible and should be supported. Best reagards, IlyaI was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo?Nope.Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening? Thanks.Definitely not. Classes require vtable's to work. Vtables are generated as part of TypeInfo. No TypeInfo, no classes, simple to understand.
Sep 10 2017
On Sunday, 10 September 2017 at 08:56:11 UTC, rikki cattermole wrote:On 10/09/2017 9:40 AM, Yuxuan Shui wrote:You sure can do that in C++, since Windows 3.x days. The constraint is that C++ compiler needs to be the same on both sides. Then there is COM as language neutral vtable.I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo?Nope.Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening? Thanks.Definitely not. Classes require vtable's to work. Vtables are generated as part of TypeInfo. No TypeInfo, no classes, simple to understand. Same reason why you can't use classes and cross the dll boundary on Windows. ....
Sep 10 2017
On 9/10/2017 1:40 AM, Yuxuan Shui wrote:I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo? Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening?Yes, we do want to move towards "Better C++" working in an analogous manner, and that means removing the typeinfo dependency.
Sep 10 2017
On Sunday, 10 September 2017 at 09:31:55 UTC, Walter Bright wrote:Yes, we do want to move towards "Better C++" working in an analogous manner, and that means removing the typeinfo dependency.TypeInfo is cheap and useful with classes. You shouldn't be removing it, just stripping it to the minimum needed so the rest is opt in.
Sep 10 2017
On Sunday, 10 September 2017 at 09:31:55 UTC, Walter Bright wrote:On 9/10/2017 1:40 AM, Yuxuan Shui wrote:If TypeInfo for extern(C++) classes is removed, couldn't final extern(C++) classes without base class and which don't implement any interfaces omit the vtable so that the following assert holds: --- final extern(C++) class Foo {} static assert (__traits(classInstanceSize, Foo) == 0LU); --- The reason I ask is that fairly often I have an abstraction that's better suited as a reference type than a value type, but doesn't need any runtime polymorphy (or the monitor standard classes have). Structs + pointers are the only way I know of to avoid the (in this special case) unneeded vtable overhead, but it always ends up looking worse to read.I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo? Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening?Yes, we do want to move towards "Better C++" working in an analogous manner, and that means removing the typeinfo dependency.
Sep 10 2017
On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:If TypeInfo for extern(C++) classes is removed, couldn't final extern(C++) classes without base class and which don't implement any interfaces omit the vtable so that the following assert holds: --- final extern(C++) class Foo {} static assert (__traits(classInstanceSize, Foo) == 0LU); --- The reason I ask is that fairly often I have an abstraction that's better suited as a reference type than a value type, but doesn't need any runtime polymorphy (or the monitor standard classes have). Structs + pointers are the only way I know of to avoid the (in this special case) unneeded vtable overhead, but it always ends up looking worse to read.We can do it for any class if its final. The problem isn't generating the vtable's. But the information required for casting.
Sep 10 2017
On Sunday, 10 September 2017 at 14:04:20 UTC, rikki cattermole wrote:On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:Even final classes can always inherit (potentially already overridden) virtual methods from their parent classes and since all normal D classes inherit from core.object : Object [1], which defines virtual methods (`toString`, `toHash`, `opCmp, and `opEquals`), I don't see how this can be true.If TypeInfo for extern(C++) classes is removed, couldn't final extern(C++) classes without base class and which don't implement any interfaces omit the vtable so that the following assert holds: --- final extern(C++) class Foo {} static assert (__traits(classInstanceSize, Foo) == 0LU); --- The reason I ask is that fairly often I have an abstraction that's better suited as a reference type than a value type, but doesn't need any runtime polymorphy (or the monitor standard classes have). Structs + pointers are the only way I know of to avoid the (in this special case) unneeded vtable overhead, but it always ends up looking worse to read.We can do it for any class if its final.The problem isn't generating the vtable's. But the information required for casting.This applies to normal D classes, but D doesn't support (dynamic) casts for extern(C++) classes, anyway, so this shouldn't be an issue for them. [1] https://github.com/somzzz/druntime/blob/74882c8a48dd8a827181e3b89c4f0f205c881ac5/src/object.d#L50
Sep 10 2017
On Sunday, 10 September 2017 at 14:42:42 UTC, Moritz Maxeiner wrote:On Sunday, 10 September 2017 at 14:04:20 UTC, rikki cattermole wrote:With a final class reference, we always know what function to call at compile time (since it can't be inherited). Therefore we don't need a vtable.On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:Even final classes can always inherit (potentially already overridden) virtual methods from their parent classes and since all normal D classes inherit from core.object : Object [1], which defines virtual methods (`toString`, `toHash`, `opCmp, and `opEquals`), I don't see how this can be true.If TypeInfo for extern(C++) classes is removed, couldn't final extern(C++) classes without base class and which don't implement any interfaces omit the vtable so that the following assert holds: --- final extern(C++) class Foo {} static assert (__traits(classInstanceSize, Foo) == 0LU); --- The reason I ask is that fairly often I have an abstraction that's better suited as a reference type than a value type, but doesn't need any runtime polymorphy (or the monitor standard classes have). Structs + pointers are the only way I know of to avoid the (in this special case) unneeded vtable overhead, but it always ends up looking worse to read.We can do it for any class if its final.The problem isn't generating the vtable's. But the information required for casting.This applies to normal D classes, but D doesn't support (dynamic) casts for extern(C++) classes, anyway, so this shouldn't be an issue for them. [1] https://github.com/somzzz/druntime/blob/74882c8a48dd8a827181e3b89c4f0f205c881ac5/src/object.d#L50
Sep 10 2017
On Sunday, 10 September 2017 at 15:12:12 UTC, Yuxuan Shui wrote:On Sunday, 10 September 2017 at 14:42:42 UTC, Moritz Maxeiner wrote:--- class Base { string name() { return "Base"; } } class ChildA : Base { override string name() { return "ChildA"; } } final class ChildB : Base { override string name() { return "ChildB"; } } void foo(Base b) { import std.stdio; b.name.writeln; } void main(string[] args) { Base b; if (args.length > 1) b = new ChildA; else b = new ChildB; b.foo(); } --- It is not known at compile time which class `foo`'s parameter `b` will actually be an instance of (Base, ChildA, or ChildB), so static dispatch is not possible; it requires dynamic dispatch. Since dynamic dispatch for classes is done in D via vtables, ChildB needs a vtable.On Sunday, 10 September 2017 at 14:04:20 UTC, rikki cattermole wrote:With a final class reference, we always know what function to call at compile time (since it can't be inherited). Therefore we don't need a vtable.On 10/09/2017 2:19 PM, Moritz Maxeiner wrote:Even final classes can always inherit (potentially already overridden) virtual methods from their parent classes and since all normal D classes inherit from core.object : Object [1], which defines virtual methods (`toString`, `toHash`, `opCmp, and `opEquals`), I don't see how this can be true.If TypeInfo for extern(C++) classes is removed, couldn't final extern(C++) classes without base class and which don't implement any interfaces omit the vtable so that the following assert holds: --- final extern(C++) class Foo {} static assert (__traits(classInstanceSize, Foo) == 0LU); --- The reason I ask is that fairly often I have an abstraction that's better suited as a reference type than a value type, but doesn't need any runtime polymorphy (or the monitor standard classes have). Structs + pointers are the only way I know of to avoid the (in this special case) unneeded vtable overhead, but it always ends up looking worse to read.We can do it for any class if its final.
Sep 10 2017
On Sunday, 10 September 2017 at 09:31:55 UTC, Walter Bright wrote:On 9/10/2017 1:40 AM, Yuxuan Shui wrote:Is there a plan? Are there any simple tasks I can take/help?I was experimenting with -betterC and found out that C++ classes doesn't work. Because the resulting object file needs a symbol "_D14TypeInfo_Class6__vtblZ" which is in druntime. I suppose this is to support T.classinfo? Could we remove T.classinfo and make classes work under -betterC? Or is there some other reason preventing this from happening?Yes, we do want to move towards "Better C++" working in an analogous manner, and that means removing the typeinfo dependency.
Sep 10 2017
On 9/10/2017 7:01 AM, Yuxuan Shui wrote:Is there a plan? Are there any simple tasks I can take/help?I filed an enhancement request: https://issues.dlang.org/show_bug.cgi?id=17822 The rest is kinda up to me.
Sep 10 2017
By the way, can we dynamic_cast extern(C++) classes in C++? If not, what are we generating these TypeInfo_Class for?
Sep 10 2017
On Sunday, 10 September 2017 at 15:08:50 UTC, Yuxuan Shui wrote:By the way, can we dynamic_cast extern(C++) classes in C++?It doesn't work for me OOTB with dmd 2.075, at least (though I may be missing something): --- classes.d --- import core.memory; extern(C++) class Parent { char id() { return 'P'; } } extern(C++) class Child : Parent { override char id() { return 'C'; } } extern(C++) Parent makeParent() { auto p = new Parent; GC.addRoot(cast(void*) p); return p; } extern(C++) Child makeChild() { auto c = new Child; GC.addRoot(cast(void*) c); return c; } extern(C++) void releaseParent(Parent p) { GC.removeRoot(cast(void*) p); } extern(C++) void releaseChild(Child c) { GC.removeRoot(cast(void*) c); } ----------------- --- main.cc --- #include <iostream> class Parent { public: virtual char id(); }; class Child : public Parent { }; extern Parent* makeParent(); extern Child* makeChild(); extern void releaseParent(Parent* p); extern void releaseChild(Child* c); extern "C" void rt_init(); extern "C" void rt_term(); bool isChild(Parent* p) { return nullptr != dynamic_cast<Child*>(p); } int main(int argc, char** argv) { rt_init(); Parent* p = makeParent(); Child* c = makeChild(); std::cout << p->id() << "\n"; std::cout << c->id() << "\n"; std::cout << "identifier\tChild\n"; std::cout << "p\t" << isChild(p) << "\t"; std::cout << "c\t" << isChild(c) << "\t"; releaseChild(c); releaseParent(p); rt_term(); return 0; } --------------- --- Compile&Link --- $ dmd -c classes.d $ g++ -std=c++11 -o main main.cc classes.o -L/path/to/dmd-2.075/lib64/ -lphobos2 /tmp/ccwjJ9Xe.o: In function `isChild(Parent*)': main.cc:(.text+0x20): undefined reference to `typeinfo for Parent' /tmp/ccwjJ9Xe.o:(.rodata._ZTI5Child[_ZTI5Child]+0x10): undefined reference to `typeinfo for Parent' collect2: error: ld returned 1 exit status --------------------
Sep 10 2017
On 9/10/2017 8:08 AM, Yuxuan Shui wrote:By the way, can we dynamic_cast extern(C++) classes in C++?No. Generally, one would need C++ RTTI for that to work, and that: 1. is specific to the particular C++ compiler 2. is undocumented, half-documented, or wrongly documented 3. requires the C++ runtime library to work It's certainly possible to do this, but requires time, effort, and a certain willingness to deal with the dirty underbelly of undocumented binary formats.If not, what are we generating these TypeInfo_Class for?It has other uses, such as providing info for associative arrays and the garbage collector.
Sep 10 2017