August 24, 2014 Re: Foreach/opApply with @nogc | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On 08/24/2014 06:40 AM, ketmar via Digitalmars-d-learn wrote: > On Sun, 24 Aug 2014 13:22:49 +0000 > Stefan Frijters via Digitalmars-d-learn > <digitalmars-d-learn@puremagic.com> wrote: > > @nogc is a part of signature. gc-function can't call @nogc-one. the > same is with calling @system function from @safe one, for example. or > impure function from pure. > > so to say, foreach() creates implicit delegate withoit '@nogc' > attribute, that's why compiler complains. > > there is currenly no way to specify attributes for such implicit > delegates. this will work, but you'll not be able to call writeln(): > > nogc: > void main() { > import std.stdio; > foreach (element; NumberRange(3, 7)) { // line 21 > //write(element, ' '); // this will fail with > // @nogc function 'z00.main.__foreachbody1' cannot call > // non-@nogc function 'std.stdio.write!(int, char).write' > } > } Yeah, the only reason why the original code does not work is the write() expression in the foreach body. If I am not mistaken, the attributes are inferred for templates and delegates; the foreach body becomes @nogc if it can be @nogc. > what we need here is something like: > > foreach (element; NumberRange(3, 7) @nogc) { ... } > > but alas... I have discovered that the following works but of course it is not the same: @nogc range = NumberRange(3, 7); foreach (element; range) { // write(element, ' '); } Ali |
August 24, 2014 Re: Foreach/opApply with @nogc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli Attachments: | On Sun, 24 Aug 2014 11:45:14 -0700 Ali Çehreli via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > Yeah, the only reason why the original code does not work is the write() expression in the foreach body. hm. really. i forgot what is delegate body for opApply. sure, here we can't use @nogc delegate. my fault. |
August 24, 2014 Re: Foreach/opApply with @nogc | ||||
---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 24 August 2014 at 18:55:09 UTC, ketmar via Digitalmars-d-learn wrote:
> On Sun, 24 Aug 2014 11:45:14 -0700
> Ali Çehreli via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com>
> wrote:
>
>> Yeah, the only reason why the original code does not work is the
>> write() expression in the foreach body.
> hm. really. i forgot what is delegate body for opApply. sure, here we
> can't use @nogc delegate. my fault.
Apologies for the misunderstanding. Before I close my enhancement request I do have a followup question: is it possible somehow to have both a @nogc and a normal opApply function available? My code would like to have @nogc in as many places as possible, but there will be places where I cannot make the foreach body @nogc (I think; maybe some more Phobos functions can be annotated as well and the problem would go away).
So I basically want something like this:
void bar() @nogc { }
void foreachBar() @nogc {
foreach (element; NumberRange(3, 7)) { bar(); }
}
void foo() { }
void foreachFoo() {
foreach (element; NumberRange(3, 7)) { foo(); }
}
void main() {
foreachBar();
foreachFoo();
}
Obviously if I have one opApply function one of the two functions complains
opapply.d(36): Error: @nogc function 'opapply.foreachBar' cannot call non-@nogc function 'opapply.NumberRange.opApply'
or
opapply.d(44): Error: function opapply.NumberRange.opApply (int delegate(ref int) @nogc operations) const is not callable using argument types (int delegate(ref int __applyArg0) @system)
If I add a second opApply function (one with @nogc, the other without) the compiler cannot distinguish between the two:
opapply.d(36): Error: NumberRange(3, 7).opApply matches more than one declaration:
opapply.d(5): const @nogc int(int delegate(ref int) @nogc operations)
and:
opapply.d(18): const int(int delegate(ref int) operations)
opapply.d(36): Error: cannot uniquely infer foreach argument types
opapply.d(44): Error: NumberRange(3, 7).opApply matches more than one declaration:
opapply.d(5): const @nogc int(int delegate(ref int) @nogc operations)
and:
opapply.d(18): const int(int delegate(ref int) operations)
opapply.d(44): Error: cannot uniquely infer foreach argument types
Is this maybe something that could be used as an enhancement request? Or I guess what I want is basically an 'inout' kind of thing for @nogc...
|
August 24, 2014 Re: Foreach/opApply with @nogc | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Frijters Attachments: | On Sun, 24 Aug 2014 19:23:01 +0000 Stefan Frijters via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > request I do have a followup question: is it possible somehow to have both a @nogc and a normal opApply function available? you can use templated opApply(): import std.traits; struct NumberRange { int begin; int end; int opApply(Dg) (scope Dg dg) if (ParameterTypeTuple!Dg.length == 1) { int result = 0; for (int number = begin; number != end; ++number) { result = dg(number); if (result) { break; } } return result; } } void bar() @nogc { } void foreachBar() @nogc { foreach (int element; NumberRange(3, 7)) { bar(); } } void foo() { } void foreachFoo() { foreach (int element; NumberRange(3, 7)) { foo(); } } void main() { foreachBar(); foreachFoo(); } this works, but you must use foreach (int n; NumberRange(3, 7)) { ... } instead of foreach (n; NumberRange(3, 7)) { ... } 'cause compiler can't infer types in the last case. |
Copyright © 1999-2021 by the D Language Foundation