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.

Reply via email to