digitalmars.D.learn - Is this nogc? dmd and gdc disagree
- rcorre (33/33) Feb 10 2016 I recently tried compiling enumap with GDC, and found that it
- tsbockman (10/14) Feb 10 2016 I cannot reproduce your results. Your example won't compile for
- tsbockman (8/11) Feb 10 2016 Here's an @nogc version of `byKeyValue()`:
- rcorre (5/17) Feb 11 2016 I'm on the DMD 2.070 release, so maybe its fixed in master.
I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is nogc. Here's a semi-reduced test-case: --- import std.range; import std.traits : EnumMembers; import std.typecons : tuple, staticIota; import std.algorithm : map; struct Enumap(K, V) if(EnumMembers!K == staticIota!(0, EnumMembers!K.length)) { enum length = EnumMembers!K.length; private V[length] _store; ref auto opIndex(K key) inout { return _store[key]; } nogc auto byKeyValue() const { return only(EnumMembers!K).map!(key => tuple(key, this[key])); } } nogc void main() { import std.typecons : tuple; import std.algorithm : map; enum E { a, b, c, d }; immutable elements = Enumap!(E, int)([1,2,3,4]); auto pairs = elements.byKeyValue.map!(pair => tuple(pair[0], pair[1] + 1)); } --- GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure.
Feb 10 2016
On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:GDC claims that byKeyValue() allocates a closure, but DMD is just fine with me calling it nogc. I'm inclined to agree with GDC here, unless DMD is doing some magic so that actually doesn't allocate a closure.I cannot reproduce your results. Your example won't compile for me with DMD HEAD: source/app.d(16,14): Error: function app.Enumap!(E, int).Enumap.byKeyValue is nogc yet allocates closures with the GC source/app.d(17,37): app.Enumap!(E, int).Enumap.byKeyValue.__lambda1 closes over variable this at source/app.d(16,14) source/app.d(26,26): Error: template instance app.Enumap!(E, int) error instantiating
Feb 10 2016
On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is nogc. Here's a semi-reduced test-case:Here's an nogc version of `byKeyValue()`: nogc auto byKeyValue() const { static immutable keys = [EnumMembers!K]; return zip(keys[], _store[]); } Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V.
Feb 10 2016
On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:I'm on the DMD 2.070 release, so maybe its fixed in master. Either way, thanks for the suggestion! Somehow I didn't realize what I was doing was an over-complicated zip :)I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is nogc. Here's a semi-reduced test-case:Here's an nogc version of `byKeyValue()`: nogc auto byKeyValue() const { static immutable keys = [EnumMembers!K]; return zip(keys[], _store[]); } Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V.
Feb 11 2016
On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote:On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:Though it appears (in 2.070 at least) that zip's range primitives aren't nogc: --- import std.range; immutable a = [1,2,3]; immutable b = [1,2,3]; nogc void main() { foreach(x, y ; a[].zip(b[])) { } } --- other.d(7): Error: nogc function 'D main' cannot call non- nogc function 'std.range.Zip!(immutable(int)[], immutable(int)[]).Zip.empty' other.d(7): Error: nogc function 'D main' cannot call non- nogc function 'std.range.Zip!(immutable(int)[], immutable(int)[]).Zip.popFront' ---Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V.I'm on the DMD 2.070 release, so maybe its fixed in master. Either way, thanks for the suggestion! Somehow I didn't realize what I was doing was an over-complicated zip :)
Feb 11 2016
On Thursday, 11 February 2016 at 12:55:02 UTC, rcorre wrote:Though it appears (in 2.070 at least) that zip's range primitives aren't nogc:I took a look at the source code for `zip()`, and the cause of this deficiency is that `Zip` takes a `StoppingPolicy` as a runtime parameter, rather than a compile-time parameter as it should. `empty()` and `popFront()` can both throw - but only if `StoppingPolicy.requireSameLength` is selected. The default is `StoppingPolicy.shortest`. This design dates back to 2009, which is probably before `nothrow` was implemented, and certainly before ` nogc`.
Feb 11 2016
On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote:On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote:You'll encounter this pretty often in Phobos I think. I really don't think nogc is ready, and tend to avoid it in my code. Exceptions are a big reason for it, and lots of functions in Phobos throw exceptions which prevents them from being used in nogc (barring ugly hacks). I don't want to discourage you before you try it, but I feel like nogc is not yet worth using until something is done about issues such as exceptions, allowing Phobos to properly be able to handle nogc.On Thursday, 11 February 2016 at 03:09:51 UTC, rcorre wrote:I'm on the DMD 2.070 release, so maybe its fixed in master. Either way, thanks for the suggestion! Somehow I didn't realize what I was doing was an over-complicated zip :)I recently tried compiling enumap with GDC, and found that it disagrees with DMD on whether a function is nogc. Here's a semi-reduced test-case:Here's an nogc version of `byKeyValue()`: nogc auto byKeyValue() const { static immutable keys = [EnumMembers!K]; return zip(keys[], _store[]); } Using zip and slices guarantees that the structure returned will be only 5*size_t.sizeof bytes, regardless of the types of K and V.
Feb 12 2016
On Friday, 12 February 2016 at 23:46:09 UTC, Kapps wrote:You'll encounter this pretty often in Phobos I think. I really don't think nogc is ready, and tend to avoid it in my code. Exceptions are a big reason for it, and lots of functions in Phobos throw exceptions which prevents them from being used in nogc (barring ugly hacks). I don't want to discourage you before you try it, but I feel like nogc is not yet worth using until something is done about issues such as exceptions, allowing Phobos to properly be able to handle nogc.On the other hand... Realistically, the only way that Phobos will reach usability with nogc, is if people keep trying and complaining when something doesn't work that should. I guess the problem is that a lot of this stuff requires RC exceptions to be realistically fixable. (Not this case though.)
Feb 12 2016
On Saturday, 13 February 2016 at 00:41:35 UTC, tsbockman wrote:On Friday, 12 February 2016 at 23:46:09 UTC, Kapps wrote:Yeah. I originally intended to go through and make what I needed nogc, but then I realized that it was pointless thanks to exceptions. Hopefully one day...You'll encounter this pretty often in Phobos I think. I really don't think nogc is ready, and tend to avoid it in my code. Exceptions are a big reason for it, and lots of functions in Phobos throw exceptions which prevents them from being used in nogc (barring ugly hacks). I don't want to discourage you before you try it, but I feel like nogc is not yet worth using until something is done about issues such as exceptions, allowing Phobos to properly be able to handle nogc.On the other hand... Realistically, the only way that Phobos will reach usability with nogc, is if people keep trying and complaining when something doesn't work that should. I guess the problem is that a lot of this stuff requires RC exceptions to be realistically fixable. (Not this case though.)
Feb 13 2016