August 24, 2014
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
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
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
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.


1 2
Next ›   Last »