C `restrict` keyword in D

Uknown via Digitalmars-d digitalmars-d at puremagic.com
Sun Sep 3 19:43:48 PDT 2017


On Sunday, 3 September 2017 at 16:55:51 UTC, Moritz Maxeiner 
wrote:
> 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); }
> ---

Yes. But this is what makes them so useful. You don't have to 
worry about null dereferences.

>>
>> 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.

Indeed. I just wrote it to emphasize on the fact that its 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.

I'm not sure I understand how one could switch between pointers 
and refs at runtime. Could you please elaborate a bit or link to 
an example? Thanks.

>> 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

Yep!
I feel there's little point in discussing the introduction of a 
new keyword if it only works on returning `ref` and has none of 
the original optimization advantages C brought.

On a side note, C99 added `inline` and `restrict`, 2 new 
keywords, without any worry of potentially breaking existing 
code. Normally they would have dded _Restrict and _Inline, and 
then #defined those.


More information about the Digitalmars-d mailing list