ref parameters: there is no escape

dsimcha dsimcha at yahoo.com
Sun Aug 14 08:41:38 PDT 2011


Another example of why this is a bad idea:

In std.parallelism, I have a function called TaskPool.put, which takes a 
Task object by reference, takes its address and puts it on the task 
queue.  This is used for scoped tasks.  However, it's safe because Task 
has a destructor that waits for the task to be finished and out of the 
task queue before destroying the stack frame it's on and returning.

Why can't we just establish a strong convention that, if a function 
truly escapes the address of a ref parameter (meaning it actually lives 
longer than the lifetime of the function), you take a pointer instead of 
a ref?  It's not like escaping ref parameters unintentionally is a 
common source of bugs.

My point is that any rule we come up with will always be conservative. 
D is a **systems language** and needs to give the benefit of the doubt 
to assuming the programmer knows what he/she is doing.  If you want 
extra checks, that's what SafeD is for.

On 8/14/2011 10:20 AM, Andrei Alexandrescu wrote:
> Walter and I have had a long discussion and we thought we'd bring an
> idea for community review.
>
> We believe it would be useful for safety purposes to disallow escaping
> addresses of ref parameters. Consider:
>
> class C {
> int * p;
> this(ref int x) {
> p = &x; // escapes the address of a ref parameter
> }
> }
>
> Such code is accepted today. We believe it is error-prone and dangerous,
> particularly because the caller has no syntactic cue that the address of
> the parameter is passed into the function (in this case constructor).
> Worse, such a function cannot be characterized as @safe.
>
> So we want to make the above an error. The workaround is obvious - just
> take int* as a parameter instead of ref int. What a function can do with
> a ref parameter in general is:
>
> * use it directly just like a local;
>
> * pass it down to other functions (which may take it by value or
> reference);
>
> * pass its address down to pure functions because a pure function cannot
> escape the address anyway (cool insight by Walter);
>
> * take its address as long as the address doesn't outlive the frame of
> the function.
>
> The third bullet is not easy to implement as it requires flow analysis,
> but we may start with a conservative version first. Probably there won't
> be a lot of broken code anyway.
>
> Please chime in with any comments you might have!
>
>
> Thanks,
>
> Andrei



More information about the Digitalmars-d mailing list