auto storage class - infer or RAII?

Sean Kelly sean at f4.ca
Mon Nov 13 12:05:20 PST 2006


Walter Bright wrote:
> Carlos Santander wrote:
>> I don't think they're valid concerns (meaning they're subjective, not 
>> everyone will have those ideas), but I think we (the D community) just 
>> want a way to clearly differentiate both meanings of auto. So, choose 
>> any two words: auto/scope, var/auto, def/scoped, foo/bar, and let's 
>> move on.
> 
> I think the auto/scope is probably the best idea.
> 
>> Also keep in mind that your option #5 (auto c = Class()) doesn't seem 
>> to be a popular proposal (based on what has been said in the ng).
> 
> I'm a bit surprised at that, but the negative reaction to it is pretty 
> clear.

Seems I was one of the few who actually sort of liked the proposals.  So 
where do we stand now?  I couldn't see much of a consensus.  I gather 
that type inference may remain as is, since it works, is clear (IMO), 
and doesn't introduce any new keywords.  But I'm a bit fuzzy on whether 
anything was decided for RAII.  Most folks seem to dislike the original 
proposal for two reasons:

* It conflicts with static opCall.
* It isn't easy to distinguish/grep such a declaration vs. a 'new' 
declaration.

And most seem to favor the addition of a new keyword, probably 'scope' 
somewhere in the declaration.  popular form seems to be:

     scope MyClass c = new MyClass(); // scoped decl
     auto scope c    = new MyClass(); // inferred scoped decl

Is this correct so far?  And if so, I'd like to re-iterate my concerns 
about such a syntax:

With the above, the 'scope' identifier is associated with the reference, 
not the data.  Thus, it would be equivalent to:

     MyClass c = new MyClass();
     scope(exit) delete c;

This raises a host of issues if such references are reassignable, and in 
the worst case would mean that scoped data could not be allocated on the 
stack unless the compiler had some form of escape detection.  For example:

     scope MyClass c = new MyClass();
     c = new MyClass();
     MyClass d = c;
     return d;

Here, we have a new instance of MyClass that should be destroyed on 
scope exit (by my understanding).  However, c is reassigned to a new 
instance of MyClass before this occurs.  The current result is that the 
new instance is destroyed instead of the old one and the old one will 
remain in memory until the next GC collection.  Also, 'd' will return a 
reference to data that no longer exists since it will be destroyed when 
'c' goes out of scope.  Even worse:

     scope MyClass c = new MyClass();
     scope MyClass d = c;

Here, we have two scoped references both referring to the same piece of 
data, which results in a double-deletion.  Therefore, to be implemented 
correctly and safely, such references must uniquely refer to the 
underlying data, much like C++'s auto_ptr.  Finally:

     scope int* i = new int;

What happens here?  Will the compiler disallow the use of 'scope' on 
non-class types, will 'i' be deleted on scope exit, or will 'scope' 
simply be ingored?

If we are truly to use the 'scope' keyword for RAII objects, I humbly 
request that the data be flagged instead of the reference.  Here are two 
suggestions for syntax:

     MyClass c = scope MyClass();
     MyClass c = new(scope) MyClass();

Both would allow data to be allocated on the stack without escape 
detection (or an assumption that the user isn't being evil), and the 
latter is even almost identical to how alloca is used now.  I dislike 
that both would make class allocation semantically different from 
concrete type allocation, but anything is better than associating 
'scope' with the reference itself, for the reasons illustrated above.


Sean



More information about the Digitalmars-d mailing list