C `restrict` keyword in D
Uknown via Digitalmars-d
digitalmars-d at puremagic.com
Sun Sep 3 08:39:58 PDT 2017
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.
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
}
void main() @safe
{
RCArray!int my_array;
...
auto t = my_array[0];//error: my_array.opIndex(0) is defined as
restrict
//This essentialy prevents a second reference from existing in
the same scope
foo(arr, arr[0]);
//error: call to foo introduces `restrict` data from the same
container
//into the scope of foo
}
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;//No longer an issue!
}
This is now no longer like the C99 keyword in behaviour, but on
the bright side, with one annotation to the return types, RCArray
suddenly doesn't need to worry about escaped references. Also, no
modifications would be needed to the foo function.
This is potentially useful for other owning container types. The
compiler could still use the information gainer from the restrict
annotation for optimizations, although such optimizations would
be much less aggressive than in C.
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
}
More information about the Digitalmars-d
mailing list