On Sunday, 3 September 2017 at 03:49:21 UTC, Moritz Maxeiner
wrote:
On Sunday, 3 September 2017 at 03:04:58 UTC, Uknown wrote:
[...]
void foo(ref RCArray!int arr, ref int val) @safe
{
{
auto copy = arr; //arr's (and copy's) reference counts are
both 2
arr = RCArray!int([]); // There is another owner, so arr
// forgets about the old payload
} // Last owner of the array ('copy') gets destroyed and
happily
// frees the payload.
val = 3; // Oops.
}
Here, adding `restrict` to foo's parameters like so :
void foo(restrict ref RCArray!int arr, restrict ref int val)
would make the compiler statically enforce the fact that
neither references are pointing to the same data. This would
cause an error in main, since arr[0] is from the same block of
memory as arr.
How does the compiler know which member of RCArray!int to check
for pointing to the same memory chunk as val?
If I understand C's version of restrict correctly, the pointers
must not refer to the same block. So extending the same here, val
should not be allowed to be a reference to any members of
RCArray!int.
This does seem to get get more confusing when the heap is
involved as a member of a struct.
e.g.
void main() @safe
{
struct HeapAsMember {
int* _someArr;
}
HeapAsMember x;
x._someArr = new int;
void foo(restrict ref HeapAsMember x, restrict ref int val) @safe
{
x._someArr = new int;
val = 0;
}
foo(x, x._someArr[0]);
}
I feel that in this case, the compiler should throw an error,
since val would be a reference to a member pointed to by
_someArr, which is a member of x. Although, I wonder if such
analysis would be feasible? This case is trivial, but there could
be more complicated cases.