Re: cannot take address of scope local in safe function

2021-06-14 Thread ag0aep6g via Digitalmars-d-learn

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();   ///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 ``, 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.


Re: cannot take address of scope local in safe function

2021-06-13 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 13 June 2021 at 17:49:50 UTC, 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();   ///Error: cannot take 
address of `scope` local `or` in `@safe` function `main`

assert(or.count == 4);
}

```


Simply remove the `scope` annotation from `or` and from the 
destructor and it works:


https://run.dlang.io/is/hElNYf

Because `OutputRange` is a `struct`, it will still be allocated 
on the stack even if you don't annotate it as `scope`.


Re: cannot take address of scope local in safe function

2021-06-13 Thread vit via Digitalmars-d-learn

On Sunday, 13 June 2021 at 17:18:46 UTC, ag0aep6g wrote:

On Sunday, 13 June 2021 at 16:27:18 UTC, vit wrote:

Why I can take address of Foo variable but not Bar?

```d
//-dip1000

struct Foo{
private double d;
}

struct Bar{
private void* ptr;
}



void main()@safe{
///this is OK:
{
scope Foo x;
scope ptr = 
}

///Error: cannot take address of `scope` local `x` in 
`@safe` function `main`:

{
scope Bar x;
scope ptr = 
}
}
```


`scope` affects indirections (i.e. pointers). `Foo` doesn't 
contain any indirections, so `scope` doesn't mean anything for 
it. The compiler just ignores it. It's like you wrote `Foo x;` 
without `scope`.


`Bar` does contain an indirection, so `scope` actually matters 
and you get the error.


Thanks.

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();   ///Error: cannot take 
address of `scope` local `or` in `@safe` function `main`

assert(or.count == 4);
}

```


Re: cannot take address of scope local in safe function

2021-06-13 Thread ag0aep6g via Digitalmars-d-learn

On Sunday, 13 June 2021 at 16:27:18 UTC, vit wrote:

Why I can take address of Foo variable but not Bar?

```d
//-dip1000

struct Foo{
private double d;
}

struct Bar{
private void* ptr;
}



void main()@safe{
///this is OK:
{
scope Foo x;
scope ptr = 
}

///Error: cannot take address of `scope` local `x` in 
`@safe` function `main`:

{
scope Bar x;
scope ptr = 
}
}
```


`scope` affects indirections (i.e. pointers). `Foo` doesn't 
contain any indirections, so `scope` doesn't mean anything for 
it. The compiler just ignores it. It's like you wrote `Foo x;` 
without `scope`.


`Bar` does contain an indirection, so `scope` actually matters 
and you get the error.


cannot take address of scope local in safe function

2021-06-13 Thread vit via Digitalmars-d-learn

Why I can take address of Foo variable but not Bar?

```d
//-dip1000

struct Foo{
private double d;
}

struct Bar{
private void* ptr;
}



void main()@safe{
///this is OK:
{
scope Foo x;
scope ptr = 
}

///Error: cannot take address of `scope` local `x` in `@safe` 
function `main`:

{
scope Bar x;
scope ptr = 
}
}
```