Re: Getting template parameters by its name
On Friday, 11 January 2019 at 04:59:50 UTC, Yui Hosaka wrote: I want to do something like this: template S(T) { } void main() { pragma(msg, S!(int).T); // Error: no property `T` for type `void` } You can get the arguments of a template instance as an AliasSeq using `std.traits.TemplateArgsOf`. https://dlang.org/phobos/std_traits.html#TemplateArgsOf
Re: Building Libraries in the face of API and ABI changes [was Understanding SIGSEGV issues]
On Thu, 2019-01-10 at 13:09 -0500, Steven Schveighoffer via Digitalmars-d- learn wrote: > […] > That is one problem with linking against C or C++ code -- changes to > certain things (e.g. struct layout) don't change the mangling. I am having nightmares trying to decide what to do with the Rust version based around generate on demand or on version change. With bindgen in Rust though, there is no need for manual tweaking so automated is possible. Except that it puts a massive dependency burden on any project using it. DStep generated bindings tend to need some manual tweaking that cannot be automated, which is surprising given that bindgen can do things without manual intervention for Rust. > You may want to consider using dpp instead if possible. DPP cannot build "out of the box" on Debian Sid, so I have not actually tried it. There are three audiences here: 1. People building libraries for their own use on their own machines. 2. People building for OS distributions. 3. People building to distribute to others who will not be building for themselves. Categories 1 and 2 could probably cope with automated generation despite the huge dependency burden, assuming there are no version conflicts – this seems to be a massive unsolved problem with Rust/Cargo/crates.io :-( . Category 3 needs as light a weight and speed of build as possible, and the ability to dynamically adapt to the APIs and ABIs of execution at run time. On the other hand, suspect I may be the sole user of RUst and D bindings to libdvbv5! -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Getting template parameters by its name
I want to do something like this: template S(T) { } void main() { pragma(msg, S!(int).T); // Error: no property `T` for type `void` } Using alias, it is possible to get T by another name: template S(T) { alias t = T; } void main() { pragma(msg, S!(int).t); } But the same identifier cannot be used: template S(T) { alias T = T; // Error: `alias T = T;` cannot alias itself, use a qualified name to create an overload set } void main() { pragma(msg, S!(int).T); } Is there any nice way that `S!(int).T` works?
Re: Segfault when adding a static destructor in druntime/src/rt/sections_elf_shared.d
On 1/10/19 5:12 PM, RazvanN wrote: On Thursday, 10 January 2019 at 15:04:25 UTC, Steven Schveighoffer wrote: On 1/8/19 7:54 AM, RazvanN wrote: [...] That is a thread-local static destructor. Are any shared static destructors accessing the array? No, there aren't. Indeed, the problem is as Johan as said: the loadedDSOs should not be wrapped in an array with a destructor because it is manually destroyed. Hm... is this a sign of how things will be once the (necessary IMO) change to destroying globals is deployed? -Steve
Re: Segfault when adding a static destructor in druntime/src/rt/sections_elf_shared.d
On Thursday, 10 January 2019 at 15:04:25 UTC, Steven Schveighoffer wrote: On 1/8/19 7:54 AM, RazvanN wrote: [...] That is a thread-local static destructor. Are any shared static destructors accessing the array? No, there aren't. Indeed, the problem is as Johan as said: the loadedDSOs should not be wrapped in an array with a destructor because it is manually destroyed. You might be able to determine this by printf debugging between calling unshared and shared destructors. -Steve
Re: Trouble with receiveOnly and immutable(JSONValue)
On Thursday, 10 January 2019 at 20:21:04 UTC, Steven Schveighoffer wrote: Thanks Steve. I suppose when the documentation talks about preferring message passing immutable data it means just use plain old receive. I can just use a template I anyway. Would you estimate this Phobos bug to be particularly hard to solve? Not sure. It would involve casting away immutable, which has to be done carefully. Probably nobody has had motivation enough to fix it yet. -Steve I might take a look at it but obviously I don’t want to screw it up if it’s complex.
Re: Trouble with receiveOnly and immutable(JSONValue)
On 1/10/19 2:36 PM, rx wrote: On Thursday, 10 January 2019 at 18:25:44 UTC, Steven Schveighoffer wrote: On 1/10/19 1:20 PM, Steven Schveighoffer wrote: I don't know if there's a specific "can't receive immutable data" issue report, but certainly, you can add your issue to the list. Actually, this one is nearly identical and quite new, you can just add to that one: https://issues.dlang.org/show_bug.cgi?id=19345 Thanks Steve. I suppose when the documentation talks about preferring message passing immutable data it means just use plain old receive. I can just use a template I anyway. Would you estimate this Phobos bug to be particularly hard to solve? Not sure. It would involve casting away immutable, which has to be done carefully. Probably nobody has had motivation enough to fix it yet. -Steve
Re: Trouble with receiveOnly and immutable(JSONValue)
On Thursday, 10 January 2019 at 18:25:44 UTC, Steven Schveighoffer wrote: On 1/10/19 1:20 PM, Steven Schveighoffer wrote: I don't know if there's a specific "can't receive immutable data" issue report, but certainly, you can add your issue to the list. Actually, this one is nearly identical and quite new, you can just add to that one: https://issues.dlang.org/show_bug.cgi?id=19345 -Steve Thanks Steve. I suppose when the documentation talks about preferring message passing immutable data it means just use plain old receive. I can just use a template I anyway. Would you estimate this Phobos bug to be particularly hard to solve?
Re: Understanding SIGSEGV issues
On Thu, Jan 10, 2019 at 01:09:22PM -0500, Steven Schveighoffer via Digitalmars-d-learn wrote: > On 1/10/19 12:30 PM, Russel Winder wrote: > > On Thu, 2019-01-10 at 10:00 -0500, Steven Schveighoffer via Digitalmars-d- > > learn wrote: > > […] > > > Hm... your description of having the problem happen at the end of > > > main seems to suggest it has something to do with destruction. > > > > > > > It seems that there was a change in one file of libdvbv5 1.14.x → > > 1..16.y that introduced a breaking change wrt the D binding. I did a > > regeneration using DStep, didn't notice anything significant, and > > yet everything now works again. So it was very significant. > > > > The underlying problem here was that I had failed to notice the > > upgrade of libdvbv5! > > > > That is one problem with linking against C or C++ code -- changes to > certain things (e.g. struct layout) don't change the mangling. Yeah, this is the same problem with shared library soname versioning on Posix. Technically everytime the ABI changes the version must be bumped, but since this is not automated, it's prone to human error, or rather, negligence. It makes one wonder if there should somehow be a way of encapsulating the changes to the ABI in a way that can be automatically checked. (It has to be automatic, otherwise it would be too onerous and nobody would do it in practice.) The most obvious way is to mangle the field types of the struct as part of the struct's mangled name, though this does introduce a lot of symbol bloat (and may need another round of ridiculously-long symbol names that need some manner of compression to keep under control). Barring that, perhaps some kind of low-collision hash of the struct contents where the kind of small changes that tend to happen in code will be highly unlikely to collide, so any such changes will be easily detected. If one were paranoid, one could use cryptographic hashes for pretty much guaranteeing uniqueness, but that'd be total overkill. // OTOH, perhaps the more pertinent issue here is that the bindings were generated *manually as a separate step* outside of the build system. Ideally, you'd automate the generation of bindings as part of your build, so that they will *always* be up-to-date. I'm a big fan of automation, because this is the kind of tedious housekeeping that humans are really, really good at forgetting and/or screwing up. (Side-note: and this is why I insist that my build systems must support generic dependency building. All these sorts of tasks *need* to be part of the build rather than done by hand, precisely to prevent these sorts of time-wasting, head-scratching mishaps.) > You may want to consider using dpp instead if possible. [...] Or this. Which is essentially equivalent to automatically generating bindings. T -- Маленькие детки - маленькие бедки.
Re: Trouble with receiveOnly and immutable(JSONValue)
On 1/10/19 1:20 PM, Steven Schveighoffer wrote: I don't know if there's a specific "can't receive immutable data" issue report, but certainly, you can add your issue to the list. Actually, this one is nearly identical and quite new, you can just add to that one: https://issues.dlang.org/show_bug.cgi?id=19345 -Steve
Re: Trouble with receiveOnly and immutable(JSONValue)
On 1/10/19 12:15 PM, rx wrote: alias SyncData = immutable(JSONValue); void worker(string filename) { SyncData data = filename.readText.parseJSON; send(ownerTid, data); } void main(string[] args) { spawn(&worker, args[1]); writeln(receiveOnly!SyncData); } I'm trying to send this immutable(JSONValue) back to the main thread but when trying to compile, I get the following error: /usr/include/dmd/phobos/std/concurrency.d(764): Error: cannot modify immutable expression ret.__expand_field_0 cc.d(15): Error: template instance `std.concurrency.receiveOnly!(immutable(JSONValue))` error instantiating Can anyone help out? Looks like a long-standing bug (there are several related issues about sending/receiving immutable data). The way std.concurrency.receiveOnly works is it creates a temporary result, then puts the received item into the result, and then returns it. But you can't copy an immutable into a temporary that's already immutable. e.g. it looks like this: immutable int x; x = 5; // error I don't know if there's a specific "can't receive immutable data" issue report, but certainly, you can add your issue to the list. -Steve
Re: Understanding SIGSEGV issues
On 1/10/19 12:30 PM, Russel Winder wrote: On Thu, 2019-01-10 at 10:00 -0500, Steven Schveighoffer via Digitalmars-d- learn wrote: […] Hm... your description of having the problem happen at the end of main seems to suggest it has something to do with destruction. It seems that there was a change in one file of libdvbv5 1.14.x → 1..16.y that introduced a breaking change wrt the D binding. I did a regeneration using DStep, didn't notice anything significant, and yet everything now works again. So it was very significant. The underlying problem here was that I had failed to notice the upgrade of libdvbv5! That is one problem with linking against C or C++ code -- changes to certain things (e.g. struct layout) don't change the mangling. You may want to consider using dpp instead if possible. -Steve
Re: Understanding SIGSEGV issues
On Thu, 2019-01-10 at 10:00 -0500, Steven Schveighoffer via Digitalmars-d- learn wrote: […] > > Hm... your description of having the problem happen at the end of main > seems to suggest it has something to do with destruction. > It seems that there was a change in one file of libdvbv5 1.14.x → 1.16.y that introduced a breaking change wrt the D binding. I did a regeneration using DStep, didn't notice anything significant, and yet everything now works again. So it was very significant. The underlying problem here was that I had failed to notice the upgrade of libdvbv5! -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Trouble with receiveOnly and immutable(JSONValue)
alias SyncData = immutable(JSONValue); void worker(string filename) { SyncData data = filename.readText.parseJSON; send(ownerTid, data); } void main(string[] args) { spawn(&worker, args[1]); writeln(receiveOnly!SyncData); } I'm trying to send this immutable(JSONValue) back to the main thread but when trying to compile, I get the following error: /usr/include/dmd/phobos/std/concurrency.d(764): Error: cannot modify immutable expression ret.__expand_field_0 cc.d(15): Error: template instance `std.concurrency.receiveOnly!(immutable(JSONValue))` error instantiating Can anyone help out?
Re: Understanding SIGSEGV issues
On Thu, 2019-01-10 at 07:36 +, Nicholas Wilson via Digitalmars-d-learn wrote: […] > Hmm, if you think the binding could be the problem you could try > using app as an alternative, see if it makes any difference. I did a proper update of the generated files of the binding, and magically everything works again. I do not recollect any change being significant, but clearly something was. So the problem is that I had failed to notice the update of libdvbv5 with a breaking change and update the binding accordingly. Of course I got lots of other good stuff done with the code by having this problem and people such as yourself commenting. Big win all round. :-) Thanks again for helping on this. -- Russel. === Dr Russel Winder t: +44 20 7585 2200 41 Buckmaster Roadm: +44 7770 465 077 London SW11 1EN, UK w: www.russel.org.uk signature.asc Description: This is a digitally signed message part
Re: Generating API documention
On Thursday, 10 January 2019 at 10:33:00 UTC, Seb wrote: On Thursday, 10 January 2019 at 07:04:52 UTC, George wrote: [...] This was actually done with Ddoc (author of the ddoc setup for Mir here) ;-) See: https://github.com/libmir/mir/tree/master/doc It uses the dlang.org Ddoc theme and customizes it a bit, but is fairly tricky to setup and maintain. Also, it doesn't work with dub. For a nice out of the box experience, I would recommend scod https://github.com/MartinNowak/scod Example project: https://github.com/MartinNowak/bloom Also note that with dpldocs.info you'll automatically get documentation for your project once its published on the Dub registry, see e.g. https://pbackus.github.io/sumtype/sumtype.html Thank you!
Re: Segfault when adding a static destructor in druntime/src/rt/sections_elf_shared.d
On 1/8/19 7:54 AM, RazvanN wrote: Hi all, I am working on issue 14650 [1] and I would like to implement a solution where static destructors are destroying global variables. However, I have the following problem in druntime/src/rt/sections_elf_shared: struct ThreadDSO { DSO* _pdso; static if (_pdso.sizeof == 8) uint _refCnt, _addCnt; else static if (_pdso.sizeof == 4) ushort _refCnt, _addCnt; else static assert(0, "unimplemented"); void[] _tlsRange; alias _pdso this; // update the _tlsRange for the executing thread void updateTLSRange() nothrow @nogc { _tlsRange = _pdso.tlsRange(); } } Array!(ThreadDSO) _loadedDSOs; For this code, I would have to create the following static destructor: static ~this() { _loadedDSOs.__dtor(); } Because Array defines a destructor which sets its length to 0. However this code leads to segfault when compiling any program with the runtime (betterC code compiles successfully). In my attempt to debug it, I dropped my patch and added the above mentioned static destructor manually in druntime which lead to the same effect. Interestingly, _loadedDSOs.__dtor runs successfully, the segmentation fault comes from somewhere higher in the call path (outside of the _d_run_main function (in rt/dmain2.d)). I'm thinking that the static destructor somehow screws up the object which is later referenced after the main program finished executing. Does someone well versed in druntime has any ideas what's happening? That is a thread-local static destructor. Are any shared static destructors accessing the array? You might be able to determine this by printf debugging between calling unshared and shared destructors. -Steve
Re: Understanding SIGSEGV issues
On 1/9/19 11:39 AM, Russel Winder wrote: On Tue, 2019-01-08 at 09:59 -0500, Steven Schveighoffer via Digitalmars-d- learn wrote: […] Russel, make sure your destructor both checks whether the underlying resource is set, and clears it to invalid when freeing it. Even types that can't be copied can be moved, or temporarily created as rvalues. When they are moved the shell they get moved out of is still destructed! So it has to have a state where it can be destroyed, even though there is no resource. I have added tests in the destructor but given the constructor should throw an exception on a failure to initialise the internal state correctly, it really ought to be unnecessary. but I guess it cant hurt being there! The point is that some libraries are not robust enough to handle freeing data multiple times. And with the way postblit/dtors work, you have to handle this properly in D. As I noted to Nicholas it seems the application is getting a valid data structure returned with invalid data and that is where the SIGSEGV is. This is really weird as I have just finished a Rust version of the same application and it works fine. And this D version used to work fine. It is a real mystery why there is a problem now. Hm... your description of having the problem happen at the end of main seems to suggest it has something to do with destruction. -Steve
Re: Segfault when adding a static destructor in druntime/src/rt/sections_elf_shared.d
On Tuesday, 8 January 2019 at 14:30:24 UTC, Johan Engelen wrote: On Tuesday, 8 January 2019 at 12:54:11 UTC, RazvanN wrote: [...] Great! (I am _extremely_ surprised that dtors are not called for globals.) [...] Thanks! This is really helpful! RazvanN
Re: Libraries, versions, API changes, and Dub
On 2019-01-10 06:44, Russel Winder wrote: It appears that libdvbv5 has undergone an (unnoticed by me till just now) version change. This raises a general question for creators of D bindings. libdvbv5 has versions 1.12.x, 1.14.x, 1.16.x, etc, following the "odd is internal, even is released" minor version number strategy. It seems wrong somehow to follow that numbering for the D binding; the binding needs to have a separate evolution. However the binding has to allow the user to choose the major.minor number of the underlying library they have – though that should perhaps be done automatically using the pkg-config system. Has anyone had previous experience of this situation and can give advice/direction so I don't have to build a solution from first principles? If you only support one version of libdvbv5 for each version of the bindings, it will be much easier. If someone wants to use an older version of libdvbv5 than the bindings support they can use and older version of the bindings. But as long as symbols aren't removed in later versions of libdvbv5 the newest versions of the bindings can be used. Even if a symbol is removed, it shouldn't be a problem until it's used. As for setting the version on the bindings you can do something like: 1.0.0+1.16.0. Where "1.0.0" is the version of the bindings and "1.16.0" is the version of libdvbv5 the bindings support. Anything after "+" in semantic versioning is metadata and doesn't have any affect. -- /Jacob Carlborg
Re: Generating API documention
On Thursday, 10 January 2019 at 07:04:52 UTC, George wrote: What do people use to generate nice looking and simple html documentation for their projects? I would be glad (and if possible), someone could share some actual instructions rather than just tell me ddoc. For example I have seen the libmir (http://docs.mir.dlang.io/latest/index.html) and I would love to generate something similar for a project I am working on. Thank you and best wishes. George This was actually done with Ddoc (author of the ddoc setup for Mir here) ;-) See: https://github.com/libmir/mir/tree/master/doc It uses the dlang.org Ddoc theme and customizes it a bit, but is fairly tricky to setup and maintain. Also, it doesn't work with dub. For a nice out of the box experience, I would recommend scod https://github.com/MartinNowak/scod Example project: https://github.com/MartinNowak/bloom Also note that with dpldocs.info you'll automatically get documentation for your project once its published on the Dub registry, see e.g. https://pbackus.github.io/sumtype/sumtype.html
Re: Libraries, versions, API changes, and Dub
On Thursday, 10 January 2019 at 10:28:55 UTC, Mike Parker wrote: to set up compile-time versions Compile-time *values* else enum dvbvSupport = DVBVSupport.v114; This, of course, should be = DVBVSupport.v112
Re: Libraries, versions, API changes, and Dub
On Thursday, 10 January 2019 at 05:44:22 UTC, Russel Winder wrote: It appears that libdvbv5 has undergone an (unnoticed by me till just now) version change. This raises a general question for creators of D bindings. libdvbv5 has versions 1.12.x, 1.14.x, 1.16.x, etc, following the "odd is internal, even is released" minor version number strategy. It seems wrong somehow to follow that numbering for the D binding; the binding needs to have a separate evolution. However the binding has to allow the user to choose the major.minor number of the underlying library they have – though that should perhaps be done automatically using the pkg-config system. Has anyone had previous experience of this situation and can give advice/direction so I don't have to build a solution from first principles? Use version conditions for the different library versions to set up compile-time versions you can static if on: ``` enum DVBVSupport { v112 = 112, v114 = 114, v116 = 116, } version(DVBV_114) { enum dvbvSupport = DVBVSupport.v114; } else version(DVBV_116) { enum dvbvSupport = DVBVSupport.v116; } else enum dvbvSupport = DVBVSupport.v114; // Declarations supported in 1.12 ... static if(dvbvSupport >= DVBVSupport.v114) { ... } static if(dvbvSupport >= DVBVSupport.v116) { ... } ``` This is how I handle it in the BindBC libraries, to which I'm porting all the active bindings from the DerelictOrg group (where I handled it with different git branches, which is a horribly confusing and inefficient way to go about it): https://github.com/BindBC The only drawback to it right now is that static if isn't supported inside enum declarations, so you'll wind up with multiple declarations of the enum, as I did with SDL_EventType here: https://github.com/BindBC/bindbc-sdl/blob/master/source/bindbc/sdl/bind/sdlevents.d#L25 static if *is* supported in class & struct delcarations, though, and you can see it used in that same file in some of the event types, like SDL_MouseButtonEvent and SDL_MouseWheelEvent: https://github.com/BindBC/bindbc-sdl/blob/master/source/bindbc/sdl/bind/sdlevents.d#L347
Re: Generating API documention
On Thursday, 10 January 2019 at 08:50:27 UTC, Anonymouse wrote: Then just dub build -ddox Naturally dub build -b ddox.
Re: Generating API documention
On Thursday, 10 January 2019 at 07:04:52 UTC, George wrote: What do people use to generate nice looking and simple html documentation for their projects? I would be glad (and if possible), someone could share some actual instructions rather than just tell me ddoc. For example I have seen the libmir (http://docs.mir.dlang.io/latest/index.html) and I would love to generate something similar for a project I am working on. Thank you and best wishes. George It's not amazing, but scod and ddox is dead simple. On phone so can't format nicely, but to your dub.json: "-ddoxTool" : "scod" Then just dub build -ddox and it will generate a docs/ directory. I use GitHub pages to host mine, automatically generated and uploaded by Travis-CI on pushes.