www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Question about scope

reply Nemanja Boric <4burgos gmail.com> writes:
Taken from 
https://github.com/dlang/druntime/pull/1750#discussion_r98181564:

```
void bar(scope char** c, scope int* n)  trusted
{
}

void foo()  safe
{
     char[100] buf;
     char* c = &buf[0];
     int n;

     bar(&c, &n);
}

void main()
{
     foo();
}
```

This doesn't compile even with dip1000, but does compile when 
`buf` is moved out of the scope. Can somebody explain why it 
fails and what needs to be done with it?
Jan 27 2017
parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/27/2017 6:36 AM, Nemanja Boric wrote:
 ```
 void bar(scope char** c, scope int* n)  trusted
 {
 }

 void foo()  safe
 {
     char[100] buf;
     char* c = &buf[0];
     int n;

     bar(&c, &n);  // Error: cannot take address of scope local c in  safe
function foo
 }

 void main()
 {
     foo();
 }
 ```

 This doesn't compile even with dip1000, but does compile when `buf` is moved
out
 of the scope. Can somebody explain why it fails and what needs to be done with
it?
(I added in the error message to your example.) Because 'buf' is local data, taking the address of 'buf' is 'scope', meaning it must not escape foo(). This means that 'c' is also inferred to be 'scope'. Taking the address of a 'scope' variable is not allowed because 'scope' is not transitive and a 'scope pointer to a scope value' is not representable. However, a 'ref' to a 'scope' is allowed, so your code can be written as: ``` void bar(ref scope char* c, scope int* n) trusted { } void foo() safe { char[100] buf; char* c = &buf[0]; int n; bar(c, &n); } void main() { foo(); } ``` If you need to build more complex structures on the stack, and have them be safe, you'll need to encapsulate things with structs and ref counting.
Jan 27 2017