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