Flatten a range of static arrays

ag0aep6g anonymous at example.com
Sat Feb 8 01:38:36 UTC 2020


On 08.02.20 01:17, Steven Schveighoffer wrote:
> The original code is not invalid though. f is not valid, and that is a 
> bug, but the original code posted by nullptr should be fine by memory 
> safety standards.

Maybe. But then it should also work with `int[3] front;`.

> If there is no possible way to do the original code with dip1000 
> attributes, then that's a bug with dip1000's design (would not be 
> surprised).

Or DIP 1000 just doesn't allow that kind of code. @safe (including DIP 
1000) is not supposed to allow all de-facto safe programs.

Simplified, we're looking at this:

----
struct Joiner
{
     int[3] _items;
     int[] _current;
}
void main() @safe
{
     Joiner j;
     j._current = j._items[];
}
----

I.e., a self-referential struct. Or most fundamentally:

----
struct Joiner
{
     Joiner* p;
}
void main() @safe
{
     Joiner j;
     j.p = &j; /* error */
}
----

`dmd -dip1000` complains about the marked line:

     Error: reference to local variable j assigned to non-scope j.p

What if I mark `j` as `scope`? Then I should be able to assign a 
reference-to-local to `j.p`. Indeed, the error goes away, but another 
takes its place:

     Error: cannot take address of scope local j in @safe function main

Right. That can't be allowed, because `scope` gives only one level of 
protection, and `&j` would need two (one for `j` itself and one for the 
thing it points at).

If that code were allowed, you could do this:

----
struct Joiner
{
     Joiner* p;
}
Joiner g;
void main() @safe
{
     scope Joiner j;
     () @trusted { j.p = &j; } (); /* pretend it's allowed */
     g = *j.p; /* dereference and copy */
}
----

Returning a copy of a dereferenced `scope` pointer is always allowed, 
because `scope` only provides one level of protection.


More information about the Digitalmars-d-learn mailing list