Cannot take slice of scope static array in @safe code

ag0aep6g anonymous at example.com
Sun Feb 2 18:49:50 UTC 2020


On 02.02.20 19:18, Steven Schveighoffer wrote:
> On 2/2/20 10:20 AM, ag0aep6g wrote:
[...]
>>      void main() @safe
>>      {
>>          int* a0;
>>          scope int** b0 = &a0; /* accepted */
>>
>>          scope int* a2;
>>          scope int** b2 = &a2; /* rejected */
>>      }
>>
>> Now it's important to realize that `scope` only applies to the 
>> top-level of the type. That means, when you dereference b0 or b2, you 
>> get a plain `int*` without any `scope` on it.
> 
> I think this is wrong. a0 is not a scope array of scope strings, it's a 
> scope array of strings. string isn't scope, it points to immutable data 
> that's on the heap or in the static segment (generally).

I don't follow. In my code, a0's type is `int*`. In the original code 
it's `string[1]`. Neither of them are `scope`.

[...]
> How does one declare "I have this array which is scope, because it's 
> storage is on the stack. But it points at things that are in the GC 
> heap, so it's cool to reference those without scope."

As far as I understand, you're describing what `scope` does:

     int[][] g1;
     int[] g2;
     void main() @safe
     {
         int[][3] arr = [[1, 2], [3, 4], [5, 6]];
         int[][] slice = arr[]; /* Inferred `scope`. */
         g1 = slice; /* Nope. `slice` is `scope`. */
         g2 = slice[0]; /* Ok. `slice[0]` is not `scope`. */
     }

> And if that is a simple matter, what about an array stored on the stack 
> of arrays stored on the stack, of references to heap data? How do I make 
> sure the heap pointers are still heap pointers, and not have to cast the 
> compiler into submission?
I'm not sure if I got it right, but like this?

     int*[][] g1;
     int*[] g2;
     int* g3;

     void main() @safe
     {
         /* An array stored on the stack, of references to heap data: */
         int*[3] a1 = [new int, new int, new int];
         /* Another such array: */
         int*[3] a2 = [new int, new int, new int];
         /* An array of those arrays, stored on the stack: */
         int*[][2] b = [a1[], a2[]];

         g1 = b[]; /* Nope. */
         g2 = b[0]; /* Nope. */
         g3 = b[0][0]; /* Ok. */
     }

> I've run into problems like this before, they aren't solvable with 
> dip1000. And string arrays are usually where it stops working because of 
> the double indirection.

My experience with DIP 1000 is more that it has many holes where leaks 
don't get detected. That has made it difficult for me to form an 
understanding of what is supposed to work and what isn't. I'd like to 
believe that I got it by now, but I'm not really sure.


More information about the Digitalmars-d-learn mailing list