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.