Thread overview |
---|
February 11, 2016 Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
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. |
February 11, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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 |
February 11, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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.
|
February 11, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to tsbockman | 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 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.
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 :)
|
February 11, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote: > On Thursday, 11 February 2016 at 04:20:13 UTC, tsbockman wrote: >> 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 :) 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' --- |
February 11, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | 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`. |
February 12, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to rcorre | On Thursday, 11 February 2016 at 12:41:16 UTC, rcorre wrote:
> 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 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.
>
> 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 :)
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.
|
February 13, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kapps | 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.)
|
February 13, 2016 Re: Is this nogc? dmd and gdc disagree | ||||
---|---|---|---|---|
| ||||
Posted in reply to tsbockman | On Saturday, 13 February 2016 at 00:41:35 UTC, tsbockman wrote:
> 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.)
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...
|
Copyright © 1999-2021 by the D Language Foundation