On Thursday, 13 September 2012 at 15:01:28 UTC, Andrei
Alexandrescu wrote:
On 9/13/12 10:53 AM, David Piepgrass wrote:
Walter and I have discussed this for quite a while. We have
recently
decided to disallow, at least in SafeD, escaping the address
of a ref
parameter. In the beginning we'll be overly conservative by
disallowing taking the address of a ref altogether. I'll
write a DIP
on that soon.
Err, wouldn't that break a lot of stuff, a lot of which is
actually safe
code?
void a(ref int x) { b(&x); }
void b(int* x) { if(x != null) (*x)++; }
Yes. Disallowing taking the address of a local is conservative
and would disallow a number of valid programs.
Arguably, such programs are in poor style anyway. A good
program takes pointers only if it needs to keep them around; if
all that's needed is to use the parameter transitorily or pass
it down, ref is best.
Another common reason to use a pointer (instead of ref) is if
it's optional (nullable). If the parameter is ref then the caller
must go to the trouble of creating a variable.
However, this could be solved with a feature like the following:
int* find(string searchString, out int index) { ... }
// _ means "don't care", assuming no variable "_" is defined
void caller() { find("foo", out _); }
In fact this is arguably better for 'out' variables since the
callee (find) no longer has to check whether 'index' is null
before assigning it. However this doesn't totally solve the
problem for 'ref' parameters, since such parameters are both
output and input parameters and the programmer may want 'null' to
have some special meaning as an input.
Escaping the addresses of stack variables, not just ref
parameters, is a
general problem in "safe" D. Do you have any ideas about that?
Btw just a simple illustrative example:
int* unsafe1() { int x = 1; return unsafe2(&x); }
int* unsafe2(int* x) { return x; }
int unsafe3() { int y = 7; *unsafe1() = 8; return y; }
enum gaff = unsafe3(); // ICE, no line number given
Same thing. By and large safe programs will need to make more
use of the garbage collector than others. It's the way things
work; stack allocation can be made safer if we add typed
regions, but that's a very significant escalation of
complication. There is no simple solution to this today.
Same thing meaning that you'd propose disallowing taking the
address of a stack variable in SafeD? (I guess this would include
escaping 'this' within a struct.)