Andrei Alexandrescu wrote:
grauzone wrote:
Andrei Alexandrescu wrote:
Something just dawned on me: in safe mode, struct static member
functions will be preferred to struct non-static member functions.
Why?
Consider:
struct List(T) {
T payload;
List * next;
void prepend(List * newNode) {
newNode.next = &this;
}
}
This code can't make it in safe mode because it takes the address of
this. In general, the compiler must assume that you might have
created a List object on the stack, e.g.:
List * someFun() {
List local;
List * lst = new List;
local.prepend(lst);
return lst;
}
Now even if there is no ostensible local address taking, the code is
in error because it has escaped the address of a local.
So prepend() cannot be compiled. The way to make it compile in safe
mode is:
struct List(T) {
T payload;
List * next;
static void prepend(List * zis, List * newNode) {
newNode.next = zis;
}
}
Now the code compiles and is actually safe because it is impossible
to pass the address of a local into prepend.
Maybe I don't get it, but how to you call prepend() from safe code?
module(safe) wyda;
void main() {
auto lst1 = new List;
auto lst2 = new List;
List.prepend(lst1, lst2)
}
I see... in this case, I'd say the user should be forced to allocate
List on the heap by making List a class. Of course, you could say that
it should be useable in other, unsafe, contexts too (maybe you want to
construct a list of the stack); but then you could use... InSitu!(T), or
what was it called?
Also, does anybody really care about SafeD, or would it be better if
we had some sort of valgrind for D? Maybe this is one of those
features which first sounded nice, but then it turned out it's better
to drop them.
I'm not sure, but clearly soundness is an important concern in
contemporary languages.
Andrei