Re: C++ constructors, destructors and operator access
On Saturday, 18 May 2013 at 22:23:51 UTC, Igor Stepanov wrote: At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? you can do this yourself just with mixins and templates, but the real problem is c++ abi and name mangling. so you will need to do runtime search for c++ mangled names and which runtime used, get it and call placement new and ctor(with the help of asm{} of course), do the same for other operators. it is possible, but this is never be safe at least due to non-standardized name mangling. you can write small library which would help doing this all if you really want this.
Re: C++ constructors, destructors and operator access
Igor Stepanov wazar.leoll...@yahoo.com wrote in message news:pckdwxwvumenyzbuv...@forum.dlang.org... Yes, language shouldn't be modified for the sake of one goal. But do you think, that calling C++ constructors from D is not typical task? I sure, that we must get a common way to bind C++ classes to D. No templates, no exceptions. But operators and constructors/destructors is needed. It may be special tool, that eat C++ header and return D file + C++ glue file. This util should transform all fields and constructors to D final methods for extern(C++) interface. In addition to this tool we can make a D binding layer, which simplify typical operations such as creating C++ objects using ::operator new() (or class operator new() if in exists) and destroying with operator delete() (local or global). Mapping constructors is complicated... Do they have the same semantics in both languages? Both on the heap and on the stack? Eg. how on earth do you map a default constructor for a struct? Same problems with destructors. Which allocator do you use for the heap? etc Operator overloads are much worse, they just don't all map. Do we support part of the set? Or add the missing ones to D? eg comparison operators By the way: Why D disallow static __gshared C++ variables in classes? This is a principled feature (if yes: why?) or omission? It does? Is this problem linux only? I don't see any reason why it would be excluded on purpose. That said, extern(C++) is mostly untested. There are some truly awful bugs lurking if you try to use complicated types/declarations. This is slowly improving.
Re: C++ constructors, destructors and operator access
Mapping constructors is complicated... Operator overloads are much worse, they just don't all map. You have misunderstood me. I spoke out against the mapping. I spoke only about access. For example if we automatically generate a binding extern(C++) interface we can add a special methods to access to operators and constructors/destructors. For example: С++: class Foo { int operator(const Foo); int operator(const Foo); int operator[](size_t); Foo(); ~Foo(); }; D automatically generated interface: extern(C++) interface Foo { final int __operator_lt(const Foo); final int __operator_gt(const Foo); final ref int __operator_index(size_t); final void __constructor(); final void __destructor(); } Those operator-access methods shouldn't have operator semantic in D. If user want to use C++ __operator_lt for compare objects in D, him cat manually create opCmp method and use __operator_lt in it. But it is user task. I think, we should only provide access to operators and constructors methods. About constructors: In addition those methods we can add some information methods. For example size_t __sizeof() method which return size of this object. After this we can provide some allocate+constructor functions. For example: auto foo = cppNewClass!Foo(args); This template functions perform next actions: 1. Try to find overloaded operator new(). If overloaded new has been finded then cppNewClass will use it, otherwise cppNewClass will use default new. 2. Try to find constructor, which can called with specified args. 3. Allocate memory using __sizeof() method. 4. Call constructor over alloated memory. for pair to cppNewClass can be provided cppDeleteClass function with same semantic. This support layer will very simplify interface with C++ code. By the way: Why D disallow static __gshared C++ variables in classes? This is a principled feature (if yes: why?) or omission? It does? Is this problem linux only? I don't see any reason why it would be excluded on purpose. Ok. I've created pull request https://github.com/D-Programming-Language/dmd/pull/2053 That said, extern(C++) is mostly untested. There are some truly awful bugs lurking if you try to use complicated types/declarations. This is slowly improving. I've bumped two old bugzilla issues about extern(C++) http://d.puremagic.com/issues/show_bug.cgi?id=1687 http://d.puremagic.com/issues/show_bug.cgi?id=4620 Please comment it and close if they are invalid.
Re: C++ constructors, destructors and operator access
On Monday, 20 May 2013 at 20:11:27 UTC, nazriel wrote: On Saturday, 18 May 2013 at 22:23:51 UTC, Igor Stepanov wrote: At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? Isn't it possible already with something like: extern(C++) interface Foo { pragma(mangle, typeof(this).mangleof ~ generateCPPMangle!myOwnFunctionMangling) void foo(); } Of course I mean: extern(C++) interface Foo { pragma(mangle, generateCPPMangle!(typeof(this).mangleof, myOwnFunctionMangling)) void foo(); } AFAIK, mangle pragma was merged recently.
Re: C++ constructors, destructors and operator access
On Saturday, 18 May 2013 at 22:23:51 UTC, Igor Stepanov wrote: At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? Isn't it possible already with something like: extern(C++) interface Foo { pragma(mangle, typeof(this).mangleof ~ generateCPPMangle!myOwnFunctionMangling) void foo(); } AFAIK, mangle pragma was merged recently.
Re: C++ constructors, destructors and operator access
On Monday, 20 May 2013 at 20:13:47 UTC, nazriel wrote: On Monday, 20 May 2013 at 20:11:27 UTC, nazriel wrote: On Saturday, 18 May 2013 at 22:23:51 UTC, Igor Stepanov wrote: At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? Isn't it possible already with something like: extern(C++) interface Foo { pragma(mangle, typeof(this).mangleof ~ generateCPPMangle!myOwnFunctionMangling) void foo(); } Of course I mean: extern(C++) interface Foo { pragma(mangle, generateCPPMangle!(typeof(this).mangleof, myOwnFunctionMangling)) void foo(); } AFAIK, mangle pragma was merged recently. If we'll implement generateCPPMangle template, we'll can do all:) This way one of the possible. There are another way to do it. I don't know, what a best way now. But I think, this (simple binding C++ code to D) is important issue and we should solve it using one of the possible way.
Re: C++ constructors, destructors and operator access
No. Ok. As I know, there is running process to moving DMD front-end from C++ to D. As I remember, process expect to be gradual. Thus I the same moment will be C++ classes and D classes in the frontend. How you are planning create new C++ objects from D? Are you planning add to all classes special constructor static method, which will create new instances of C++ classes and return it, or you see another way to do it?
Re: C++ constructors, destructors and operator access
On 19 May 2013 13:20, Igor Stepanov wazar.leoll...@yahoo.com wrote: No. Ok. As I know, there is running process to moving DMD front-end from C++ to D. As I remember, process expect to be gradual. Thus I the same moment will be C++ classes and D classes in the frontend. How you are planning create new C++ objects from D? Are you planning add to all classes special constructor static method, which will create new instances of C++ classes and return it, or you see another way to do it? All new'ing will be done in D. The C++ glue-layer methods are a problem, and we will be moving to using a visitor interface between the two. -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';
Re: C++ constructors, destructors and operator access
Is this mean, that D functions will _not_ create C++ objects with new? For example: You have moved parser to D, but you haven't moved expressions to D yet. And you want to create new Expression object in parser (in D code), but Expression class defined in C++. What will you do in this case?
Re: C++ constructors, destructors and operator access
Igor Stepanov wazar.leoll...@yahoo.com wrote in message news:wuevxraaffhaaceap...@forum.dlang.org... Is this mean, that D functions will _not_ create C++ objects with new? For example: You have moved parser to D, but you haven't moved expressions to D yet. And you want to create new Expression object in parser (in D code), but Expression class defined in C++. What will you do in this case? This is not how we're moving it. The entire frontend will be moved in one go, there will never be a need to create a C++ class from D. That said, the glue layer will remain in C++ and will need to create instances of classes defined in D. The current glue layer calls 43 different constructors. I don't have a solution for this yet, but it will probably be: a) Extend D to allow creating classes with constructors callable from C++ b) Create/generate factory functions for each class new'd in the glue layer c) Remove all class allocations from the glue layer I'm leaning towards b, or maybe c, and I think you should too.
Re: C++ constructors, destructors and operator access
On Sunday, 19 May 2013 at 13:56:56 UTC, Daniel Murphy wrote: Igor Stepanov wazar.leoll...@yahoo.com wrote in message news:wuevxraaffhaaceap...@forum.dlang.org... Is this mean, that D functions will _not_ create C++ objects with new? For example: You have moved parser to D, but you haven't moved expressions to D yet. And you want to create new Expression object in parser (in D code), but Expression class defined in C++. What will you do in this case? This is not how we're moving it. The entire frontend will be moved in one go, there will never be a need to create a C++ class from D. That said, the glue layer will remain in C++ and will need to create instances of classes defined in D. The current glue layer calls 43 different constructors. I don't have a solution for this yet, but it will probably be: a) Extend D to allow creating classes with constructors callable from C++ b) Create/generate factory functions for each class new'd in the glue layer c) Remove all class allocations from the glue layer I'm leaning towards b, or maybe c, and I think you should too. Yes, language shouldn't be modified for the sake of one goal. But do you think, that calling C++ constructors from D is not typical task? I sure, that we must get a common way to bind C++ classes to D. No templates, no exceptions. But operators and constructors/destructors is needed. It may be special tool, that eat C++ header and return D file + C++ glue file. This util should transform all fields and constructors to D final methods for extern(C++) interface. In addition to this tool we can make a D binding layer, which simplify typical operations such as creating C++ objects using ::operator new() (or class operator new() if in exists) and destroying with operator delete() (local or global). By the way: Why D disallow static __gshared C++ variables in classes? This is a principled feature (if yes: why?) or omission?
C++ constructors, destructors and operator access
At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea?
Re: C++ constructors, destructors and operator access
On 05/18/2013 03:23 PM, Igor Stepanov wrote: natural C++ mangle That's part of the problem: C++ name mangling is not standardized. Ali
Re: C++ constructors, destructors and operator access
On Saturday, 18 May 2013 at 22:55:34 UTC, Ali Çehreli wrote: On 05/18/2013 03:23 PM, Igor Stepanov wrote: natural C++ mangle That's part of the problem: C++ name mangling is not standardized. Ali But D compilers are using C++ mangle for extern(C++) functions now. I think, this trouble can be solved in a glue layer of compiler. Now, on posix we can use gcc c++ mangle, on windows - dmc/visual c++ mangle. As I know, there is not many kinds of c++ mangle. over 10:) Current implementation use only two: dmc for windows, gcc for posix. If another back-end will be added, we can add another mangle support. I think, C++ to D binding is a very important issue. If D will provide good mechanism of binding, some projects will can be simple moved to D and some project leaders will can choose D to develop his projects.
Re: C++ constructors, destructors and operator access
On May 18, 2013 11:25 PM, Igor Stepanov wazar.leoll...@yahoo.com wrote: At the current time D have powerful mechanism of access to C++ classes. For access to methods of C++ classes (virtual and not) we can use extern(C++) interface. //С++ class CPPTest1 { int a; int b; public: virtual int boom(); int fun(); static int gun(); CPPTest1(int); virtual ~CPPTest1(); int operator[](size_t); }; class CPPTest2: public CPPTest1 { int boom(); }; //D extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); } extern(C++)interface CPPTest2: CPPTest1 { //int boom(); } As a rule, non-static fields are not public in C++ classes and is not part of interface. Thus the most of C++ classes can be bound without any glue c++ code. However D dont support C++ overloaded operators and constructors. Yes, we cannot make mapping C++ operators to D operators and C++ constructors to D constructors). Nonetheless С++ operators and constructors are the simple C++ functions or methods with special mangling. Thus I've suggest next mechanism: Allow special pragma(cppSymbol, string_arg), when string_arg is the name of c++ thing. Example: extern(C++)interface CPPTest1 { int boom(); static int gun(); final int fun(); /// pragma(cppSymbol, constructor) final void ctor(int); //linked with CPPTest1(int); pragma(cppSymbol, destructor) void dtor(); //linked with virtual ~CPPTest1(); pragma(cppSymbol, []) ref int indexOf(size_t); //linked with int operator[](size_t); } This pragma must apply to the function (or method), use natural C++ mangle, but set operatror or constructor or destructor mangled name instead of function name. Is it useful idea? No. Regards -- Iain Buclaw *(p e ? p++ : p) = (c 0x0f) + '0';