Destructors, const structs, and opEquals

Don nospam at nospam.com
Mon Dec 13 14:54:57 PST 2010


Andrei Alexandrescu wrote:
> On 12/13/10 9:28 AM, Don wrote:
>> Andrei Alexandrescu wrote:
>>> On 12/10/10 4:10 PM, foobar wrote:
>>>> Don Wrote:
>>>>
>>>>> Steven Schveighoffer wrote:
>>>>>> To summarize for those looking for the C++ behavior, the equivalent
>>>>>> would be:
>>>>>>
>>>>>> void foo(auto ref const Widget)
>>>>>
>>>>> That use of 'auto' is an abomination.
>>>>
>>>> I agree with don.
>>>> IMHO, this is incredibly silly given Andrei's use case, since D can
>>>> have instead:
>>>> void foo(const Widget);
>>>> and have an optimization inside the compiler for value types to pass
>>>> by ref.
>>>
>>> Everyone - please stop suggesting that. It causes severe undue
>>> aliasing issues.
>>>
>>> Andrei
>>
>> I don't understand this.
>>
>> For sure,
>> const Widget foo(const Widget x) { return x; }
>>
>> is inefficient.
>>
>> But I don't see how problems can ever arise with a function which
>> returns a built-in type (eg, opEquals() ).
>>
>> It seems to me, that the issue relates to deterministic destruction.
>>
>> As I see it, there can be two forms of const parameters:
>> * caller manages lifetime. Caller must call destructor. It must
>> duplicate anything it wants to return.
>> * callee manages lifetime. Callee must destroy the variable, or return 
>> it.
>>
>> Interestingly, any parameter marked as 'inout' is the second form.
>> Seems pretty clear to me that opEquals needs the first form.
>> And I think it's a pretty common case: I'm only going to look at this
>> variable, I'm not going to take ownership of it or modify it any way.
>>
>> We have
>> ref const in inout scope 'auto ref' (which does not mean auto + ref).
>>
>> And yet, even with this zoo of modifiers, the best syntax we have for
>> that simple situation is 'auto ref const' ???
>>
>> We've got to do better than that.
> 
> I agree we should ideally do better than that. The problem with the 
> compiler taking initiative in the ref vs. value decision is undue aliasing:
> 
> void fun(const Widget a, Widget b) { ... }
> 
> In the call fun(x, x) the compiler may or may not alias a with b - a 
> very difficult to detect bug. The two objects don't have to be 
> parameters - one could be e.g. a global.
> 
> Andrei

I can't really escape the feeling that 'const' guarantees too little.
It makes guarantees to the caller, but tells the callee *nothing*.
(Except for the (important) special case where *all* the parameters are 
const, none have destructors, and the function is pure).
I think everything we're actually doing here is trying to tie the 
semantics down, for the benefit of the callee.
So I would think that we need to be very clear about what semantics we 
can realistically guarantee, and tie the syntax to that.


BTW the really big problem I have with 'auto ref' is that it isn't 
'auto', and it isn't 'ref'. I wouldn't have the same objection to 
something like 'autoref'.




More information about the Digitalmars-d mailing list