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'.