DIP23 draft: Fixing properties redux

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Tue Feb 5 12:21:14 PST 2013


On 2/5/13 2:21 PM, Steven Schveighoffer wrote:
> On Tue, 05 Feb 2013 13:33:35 -0500, Andrei Alexandrescu
> <SeeWebsiteForEmail at erdani.org> wrote:
>
>> Walter and I reviewed the discussion and had a long talk. We are very
>> seriously considering banning the use of & against a ref result from a
>> function (and actually ref parameters and even struct members in @safe
>> code). One would still be able to take the address of a field in a
>> class because that's assumed to live on the GC heap.
>
> Back to the problem I stated, how does one do this:
>
> ref A foo();
>
> ref A bar();
>
> A *a;
>
> if(condition)
> a = &foo();
> else
> a = &bar();
>
> // use a for a few lines
>
> I can see a possible solution but it's not pretty:
>
> void processA(ref A a)
> {
> // lines that deal with a here
> }
>
> if(condition)
> processA(foo());
> else
> processA(bar());
>
> But this kind of seems hacky. Why should I have to declare a function
> just to keep a persistent reference to a return value for the scope of
> my function? Not only is is awkward, there is a performance hit in that
> I have to call another function.

You define the function in situ.

We understand some valid code will be disallowed by the change,

> Note also that this doesn't fix memory issues:
>
> struct S
> {
> ref S self() {return this;}
> }
>
> ref S bad()
> {
> S s;
> return s.self();
> }
>
> Which I believe would be valid still with your rules.

Also consider the simpler:

ref int id(ref int x) { return x; }
ref int id1(ref int x) { return id(x); }
ref int id2(ref int x) { return id1(x); }
ref int oops(int x) { return id2(x); }

DIP24 addresses that and other similar cases at their core.


Andrei



More information about the Digitalmars-d mailing list