Re: C++ parser
I'm not sure on how to best bind C++ code to D. D can handle some parts of the C++ ABI, like classes and virtual functions. dlang.org contains some information: Now extern(C++) interface allow to access to virtual and non-virtual (with final annotation) methods, static methods. After my pull for posix and fix windows mangling (in work) static variables also be allowed. I've idea, how we can get access to fields: //C++ class Foo { public: int a; int b; //virtual methods and other stuff }; //Glue C++ (automatically generated) int __accessor_Foo_a(Foo* f){return f-a;} int __accessor_Foo_b(Foo* f){return f-b;} //also we can get access to private/protected methods with some header hack if in needed //D header extern(C++) { interface Foo { //we can implement final methods in interface @property final ref int a() {return __accessor_Foo_a(this);} @property final ref int b() {return __accessor_Foo_b(this);} //other stuff } ref int __accessor_Foo_a(Foo); ref int __accessor_Foo_b(Foo); } for get access to different special functions (like constructors, destructors, operators) we can use special methods + pragma(mangle) interface Foo { pragma(mangle, getCPPOperatorMangle!(Foo.__operator_idx, [])) int __operator_idx(size_t); //get access to int Foo::operator[](size_t) } There is small trouble with inlined functions: //C++ class Foo { protected: int foo(){return 5;} //this function is inline and there's a possibility that this function won't be written into object file. }; In this case, we must to do some actions to force write foo into object file. This is my ideas about binding C++ to D :) If I'll do all as I want, we'll get a simple interface to access to most of C++ code (except templates).
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: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
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
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?
Re: QtD fails to build on Arch Linux
On Saturday, 18 May 2013 at 17:24:21 UTC, Tyler Jameson Little wrote: I'm on 64-bit, so I've used the 64-bit patch [1] on bitbucket to get the compile started. I get a lot of these errors: [ 3%] Building CXX object CMakeFiles/cpp_core.dir/cpp/qt_core/QAbstractItemModel_shell.cpp.o /home/otto/sandbox/qtd/build_dir/build/cpp/qt_core/QAbstractItemModel_shell.cpp: In member function ‘virtual QModelIndex QAbstractItemModel_QtDShell::buddy(const QModelIndex) const’: /home/otto/sandbox/qtd/build_dir/build/cpp/qt_core/QAbstractItemModel_shell.cpp:83:141: error: taking address of temporary [-fpermissive] qtd_QAbstractItemModel_buddy_QModelIndex_const_dispatch(QObjectLink::getLink(this)-dId, __d_return_value, qtd_from_QModelIndex(index0)); I'm using gcc 4.8 if that makes a difference. I've noticed that the original developers have more or less abandoned it (a patch for finding 64-bit dmd sits in the issue tracker gathering dust), but it seems to be the only Qt binding out there. I've noticed on the D forums that the developers have possibly lost interest [2]. So, has anyone else had problems building QtD recently? Is there any community interest in maintaining it? If people need it, I'd consider looking into fixing the current build status, but I can't commit to maintaining it long-term since I don't have any active projects that need it. I may in the future, hence the tentative offer to help. [1] https://bitbucket.org/qtd/repo/issue/4/cmake-finding-dmd#comment-4087437 [2] http://forum.dlang.org/thread/mailman.461.1349112690.5162.digitalmar...@puremagic.com This project very interest for me. But current QtD is supports only 4.8 Qt version. If anybody wants to revive this project and know something about Qt binding specific (this is not simple c++ binding, as I know. How bind QT_OBJECT macros?), I can to help him. Anyway, if someone tell me about QtD develop ideas, I'll be very grateful:) About this build trouble: add -fpermissive to CXXFLAGS and all will be builded and work correctly (to the best of my memory)
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 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: [challenge] Linker surgery
On Friday, 17 May 2013 at 17:57:54 UTC, Rainer Schuetze wrote: On 17.05.2013 14:29, Dmitry Olshansky wrote: 15-May-2013 04:17, IgorStepanov пишет: Do this table linked, if you remove all functions, which use it? Thanks for this try, but they DO link in always. And I believe this is a key problem - each function goes into a separate object but globals are always pulled in! Yes, if you build a library the functions in a module are split into separate object files, but data is always written into the object file of the original module. The linker cannot split these afterwards if any data in the module is referenced (which might happen by just importing the module). A workaround could be to put the data into a different module. What happens, if you place table into separate module? This module will be compiled as independent object file and (I hope) can be not linked if symbols from it will not be used. Or my logic is broken?
Re: [challenge] Linker surgery
And how then I would use these tables if even importing these modules then pulls in the data? without import with pragma(mangle) help. But this dark linker magic no much better you template solution.
Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)
On Friday, 17 May 2013 at 22:45:01 UTC, Timothee Cour wrote: Although I agree that having a default constructor would be convenient, I think the problem is that S.init should be known at compile time by the spec. Maybe we could support the following syntax, with a static this instead of this : struct S { int x=11; int y = void; static this() // hypothetical { // x would already be initialized to int.init here assert(x == int.init); // y is left uninitialized here y=x*x; } } On Fri, May 17, 2013 at 2:34 PM, Andrej Mitrovic andrej.mitrov...@gmail.com wrote: On 5/17/13, Walter Bright wal...@digitalmars.com wrote: I oppose this. D has a lot of nice features because of the .init property. Default constructors wreck that. Would they? I'm thinking the process would be: struct S { int x; int y = void; this() // hypothetical { // x would already be initialized to int.init here assert(x == int.init); // y is left uninitialized here } } Maybe that's already clear. But why is .init actually such a big problem? If it becomes arbitrarily expensive to call .init of a struct, well it's because it has to be - if the user really provided an expensive default ctor. But it's entirely the user's responsibility. So then .init can even throw, but throwing exceptions isn't a big deal. Is there some other problem? A custom default ctor in a struct is one of the most asked for features. Just yesterday we spent several hours explaining to a C++ user why a default ctor doesn't work, and what .init is for. The whole conversation could have been avoided if D had support for custom default ctors for structs. This topic comes up very often in IRC and the forums. May be we can allow default ctor, but ensure that it can be interpreted at compile time and initialize .init value with ctored value? Foo.init = Foo(); //somewhere in deep of compiler But there is one trouble. struct Foo { int[] arr; this()//can be interpreted at compile time { arr = new int[3]; arr[0] = 1; arr[1] = 2; arr[2] = 3; } } semantically, all new instances of Foo must get separate instance of array. Foo f1; Foo f2; assert(f1.arr.ptr !is f2.arr.ptr); //expects put FAILS However, if Foo.init initialized by compiler with Foo() and f1 and f2 will be initialized with Foo.init, f1.arr and f2.arr will be the same value. We can also restrict creating of any mutable reference instances in this() constructor: struct Foo { int[] arr; immutable int[] arr2; this()//can be interpreted at compile time { arr = new int[3]; //NG arr = [1,2,3]; //NG arr2 = [1,2,3]; //OK, because arr2 is immutable and all instances of foo can contains an single array instance } } But this way is so difficult and isn't much profitable.
Re: [challenge] Linker surgery
module fmod; public immutable int[] fable = [1,2,3]; module mod; //import fmod; int foo(int i) { pragma(mangle, _D4fmod5fableyAi) extern immutable int[] fable; return fable[i]; }
Re: Struct with default ctor (Was: [dmd-beta] dmd 2.064 beta take 2)
When programmer see constructor, he think that it will be evaluated each time when he create a new object. This code will seem obvious for any C++ coder. And this coder will be deceived. If we'll add default constructor to structs, we'll must safe of illusion, that constructor is called any time when new object have been created. And reject all cases when we can't provide this illusion.
Re: Why extern variables and functions within template/struct/class have a D mangling
On Wednesday, 8 May 2013 at 19:14:14 UTC, Andrej Mitrovic wrote: On 5/8/13, Dicebot m.stras...@gmail.com wrote: Well, pardon me, I probably have exceeded my allowed daily rant limit :) Don't worry, and I agree with you. But I think it's probably too late to actually change what a linkage specifier does for nested symbols. We might end up getting duplicate symbol definition errors (hello Optlink..) in completely unrelated libraries if mangling changes for these symbols. I've undestood, that function mangling is a difficult issue. But what about extern variables? Obviously, when user write (extern(C) extern int var;), he want to get extern variable with C mangling. Another way: get second parameter (symbol name) to extern attribute. E.g. extern(C, @FOO@)void FOO(int); //have C linkage and @FOO@ mangling extern(C)void FOO2(int); //have C linkage and C (or D, if FOO2 is local symbol) mangling extern(__FOO__) void FOO(int); //have D or System linkage and __FOO__ mangling However, I would like to mangling argument of extern attribute will be evaluatable form any string expression. enum MANGLING = @@@M@@@; extern(D, MANGLING) int boo();
Why extern variables and functions within template/struct/class have a D mangling
Is it correct? When I wrote next code: template Extern(string s) { mixin(static extern(C) extern int ~s~;~ alias Extern = ~s~;); } void main() { writeln(Extern!(xxx)); } I get error message undefined reference to `_D1a24__T6ExternVAyaa3_787878Z3xxxi', when I expect to get undefined reference to `xxx'? Is it error?
Re: Why extern variables and functions within template/struct/class have a D mangling
May be I need to fix that issue? What about functions? struct Foo { extern(C) void bar() { } } Is it good to set bar mangling to bar?
immuable method address and export method address.
Hello, I've two simple questions: 1. I have a structure: struct Foo { public int bar() const {return 0;} public int bar() immutable {return 1;} } How can I get immutable bar address? When I've wrote next code I've got a const bar address. Is it a bug? void main() { immutable Foo boo; int delegate() immutable dg = boo.bar; } Next question: If I write туче code, it'll be builded successfully void main() { foreach(cur; __traits(getOverloads, Foo, bar)) { void* p = cur; writeln(cur); //prints a function pointer. } } If I change protection of bar to export I've got a error: struct Foo { export int bar() const {return 0;} export int bar() immutable {return 1;} } void main() { foreach(cur; __traits(getOverloads, Foo, bar)) { void* p = cur; //Error: need 'this' to access member bar writeln(cur); } } How should it be?
Re: Help with a DMD patch
What do the lines el_combine? I do not see them in the code structure comparison.
Re: Help with a DMD patch
On Saturday, 16 March 2013 at 21:21:51 UTC, Vladimir Panteleev wrote: On Saturday, 16 March 2013 at 21:15:32 UTC, Igor Stepanov wrote: What do the lines el_combine? I do not see them in the code structure comparison. Greetings Igor, The el_combine calls are supposed to ensure correct order of evaluation. I based that code from this fragment: https://github.com/D-Programming-Language/dmd/blob/635c6b07/src/e2ir.c#L2702 Visually, it should work :) I would try to make sure that the various components of expression are correctly calculated. In particular, I am concerned the calculation of the length of a dynamic array. You can try to do so, that would return the length of the entire expression. / * In DMD * / if (t1-ty == Tarray) { retrun el_una(I64 ? OP128_64 : OP64_32, TYsize_t, el_same(earr1)); } / * In D * / int[] arr = [1,2,3]; int[] arr3 = [1,2,3,4,5]; size_t len = cast(size_t)(arr == arr3); assert(len == arr.length);
Re: Help with a DMD patch
On Saturday, 16 March 2013 at 21:49:33 UTC, Vladimir Panteleev wrote: On Saturday, 16 March 2013 at 21:42:31 UTC, Igor Stepanov wrote: On Saturday, 16 March 2013 at 21:21:51 UTC, Vladimir Panteleev wrote: On Saturday, 16 March 2013 at 21:15:32 UTC, Igor Stepanov wrote: What do the lines el_combine? I do not see them in the code structure comparison. Greetings Igor, The el_combine calls are supposed to ensure correct order of evaluation. I based that code from this fragment: https://github.com/D-Programming-Language/dmd/blob/635c6b07/src/e2ir.c#L2702 Visually, it should work :) I would try to make sure that the various components of expression are correctly calculated. In particular, I am concerned the calculation of the length of a dynamic array. You can try to do so, that would return the length of the entire expression. / * In DMD * / if (t1-ty == Tarray) { retrun el_una(I64 ? OP128_64 : OP64_32, TYsize_t, el_same(earr1)); } / * In D * / int[] arr = [1,2,3]; int[] arr3 = [1,2,3,4,5]; size_t len = cast(size_t)(arr == arr3); assert(len == arr.length); Dynamic arrays work perfectly, it's the static ones I'm having trouble with... particularly, when they're being returned from a function. From what I can tell, the situation is that I can neither copy them using el_same (it neither makes sense, as the arrays can be large, nor does the compiler let me to), nor can I take their address, because the code generator fails to process an OPaddr elem when its child is a function call. However, the same thing seems to work when calling the runtime function for array equality (the current implementation)... Probably a stupid question, but why do you want to use el_same? As I understand it, el_same creates a copy. Why not use the original, if we know that it will not change anything.
Re: template this parameters for constructors
What about template this for compile-time constructing of structs (classes?)? e.g. struct BigDecimal { this(string arg) { *this = str2Dec(arg); } template this(string arg) { enum this = str2Dec(arg); } static BigDecimal str2Dec(string arg) //can be evaluated at compile time { //... } } void main() { string str = 42.24; BigDecimal num1 = str;//Calling constructor BigDecimal.this BigDecimal num2 = 3,1415926535 8979323846 2643383279 5028841971 6939937510 5820974944 5923078164 0628620899 8628034825 3421170679 8214808651 3282306647 0938446095 5058223172 5359408128 4811174502 8410270193 8521105559 6446229489 5493038196 4428810975 6659334461 2847564823 3786783165 2712019091 4564856692 3460348610 4543266482 1339360726 0249141273 7245870066 0631558817 4881520920 9628292540 9171536436 7892590360 0113305305 4882046652 1384146951 9415116094 3305727036 5759591953 0921861173 8193261179; //Calling template this at compile time. }
Re: Russian TDPL is available for orders
The ones I recall in chapter 13 (and the only available for preview): с. 471 ...вплоть до массовой памяти лучше уж дисковой, звучит проще и сомнений меньше. Все таки имелась в виду не дисковая память, а ОЗУ. Можно ли назвать ее регулярной? на с.474 есть просто отличное предложение: По мнению программистов на функциональных языках, для такой модели вычислений органично неупорядоченное, параллельное исполнение, но до недавнего времени эти возможности существовали скорее в виде потенциальной энергии, чем как достигнутая цель. (прочел попытки с 3ей) ...для такой модели вычислений органично неупорядоченное, параллельное исполнение --- ...для такой модели вычислений естественно ... или в такую модель вычислений органично вписывается и откуда множественное число - эти ? Оригинал вроде: ...that potential was more of latent energy... С оригинала начало скорее - В среде функциональных программистов является признанным фактом, что такая модель вычислений Да, фраза немного странная. Кст до лит. редактирования она звучала так: Как было замечено в кругах программистов на функциональных языках, такая модель вычислений от природы протежирует неупорядоченное, параллельное выполнение, однако до недавнего времени эти возможности существовали скорее в форме латентной энергии, чем достигнутой цели. P.S. Ничего, что я по-русски?
Instantiate the template class method
Hi! I engaged in addition to dmd with runtime reflection and there was a problem: If we have any template class, the real instantiated only those methods that are used. And to сonstruct the runtime reflection, I need to instantiate the other methods. And here is a question: how to do it. I write code like this: static void WriteFunc(Dsymbol* root, FuncDeclaration* fd) { if(root-inTemplateInstance() fd-semanticRun PASSobj) { assert(fd-inTemplateInstance()); TemplateInstance* templ = fd-inTemplateInstance(); fd-scope-parent = root; fd-semantic(fd-scope); fd-semantic2(fd-scope); fd-semantic3(fd-scope); assert(fd); assert(fd-scope); fd-toObjFile(0); } } In the trivial case, everything is fine.But if this function has internal functions / delegates /foreach-loops I have the error. Does anyone can tell me how to correctly instantiate the template class method?