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