C `restrict` keyword in D

Moritz Maxeiner via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 3 09:55:51 PDT 2017


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




More information about the Digitalmars-d mailing list