On Sunday, 3 September 2017 at 15:39:58 UTC, Uknown wrote:
On Sunday, 3 September 2017 at 12:59:25 UTC, Moritz Maxeiner
wrote:
[...]
The main issue I see is that pointers/references can change at
runtime, so I don't think a static analysis in the compiler
can cover this in general (which, I think, is also why the C99
keyword is an optimization hint only).
Well, I thought about it, I have to agree with you, as far as
pointers go. There seems to be no simple way in which the
compiler can safely ensure that the two restrict pointers point
to the same data. But fir references, it seems trivial.
References are just non-null syntax for pointers that take
addresses implicitly on function call. Issues not related to null
that pertain to pointers translate to references, as any
(non-null) pointer can be turned into a reference (and vice
versa):
---
void foo(int* a, bool b)
{
if (b) bar(a);
else baz(*a);
}
void bar(int* a) {}
void baz(ref int a) { bar(&a); }
---
In order to do so, RCArray would have to first annotate it's
opIndex, opSlice and any other data returning member functions
with the restrict keyword. e.g.
struct RCArray(T) @safe
{
private T[] _payload;
/+some other functions needed to implement RCArray correctly+/
restrict ref T opIndex(size_t i) {
//implimentation as usual
return _payload[i];
}
restrict ref T opIndex() {
return _payload;
}
//opSlice and the rest defined similary
}
[...]
Note: There's no need to attribute the RCArray template as @safe
(other than for debugging when developing the template). The
compiler will derive it for each member if they are indeed @safe.
W.r.t. the rest: I don't think treating references as different
from pointers can be done correctly, as any pointers/references
can be interchanged at runtime.
Coming back to pointers, the only way I can see (short of
bringing Rust's borrow checker to D) is to add additional
annotations to function return values. The problem comes with
code like this :
int * foo() @safe
{
static int[1] data;
return &data[0];
}
void main()
{
int * restrict p1 = foo();
int * restrict p2 = foo();//Should be error, but the
compiler can't figure
//this out without further
annotations
}
Dealing with pointer aliasing in a generic way is a hard problem
:p