cannot take address of scope local in safe function

ag0aep6g anonymous at example.com
Mon Jun 14 09:57:00 UTC 2021


On 13.06.21 19:49, vit wrote:
> Is possible create and use scope output range allocated on stack in 
> @safe code?
> 
> Example:
> ```d
> //-dip1000
> 
>      struct OutputRange{
>          private bool valid = true;
>          private void* ptr;
>          int count = 0;
> 
>          void put(Val)(auto ref scope Val val){
>              assert(this.valid == true);
>              this.count += 1;
>          }
> 
> 
>          ~this()scope pure nothrow @safe @nogc{
>              this.valid = false;
>          }
> 
> 
>      }
> 
>      void main()@safe pure nothrow @nogc{
>          import std.algorithm : copy;
>          import std.range : only;
> 
>          scope OutputRange or;
> 
>          only(1, 2, 3, 4).copy(&or);   ///Error: cannot take address of 
> `scope` local `or` in `@safe` function `main`
>          assert(or.count == 4);
>      }
> 
> ```

You're trying to create a `scope` pointer that points to another `scope` 
pointer. That's not supported. You can only have one level of `scope`.

The first level of `scope` is explicit in `scope OutputRange or;`. The 
second level is implicit in `&or`, because the address of a local 
variable is necessarily a `scope` pointer.

As it's written, the first level isn't actually needed in your code. So 
maybe you can just remove `scope` from `or` be done. But let's assume 
that it really is needed for some reason.

The second level you do need. Without it, the assert fails. But you 
wouldn't need the pointer if `copy` took the argument by `ref`, because 
`ref` has a sort of implied `scope` that can be combined with an actual 
`scope` to give two levels of protection. So you could write your own 
`copy` with a `ref` parameter.

Or you can just write out what `copy` does in `main`, sidestepping the 
issue:

----
foreach (e; only(1, 2, 3, 4))
{
     or.put(e);
}
----

None of this is ideal, of course.


More information about the Digitalmars-d-learn mailing list