View mode: basic / threaded / horizontal-split · Log in · Help
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 00:47:04 UTC, Jonathan M Davis 
wrote:
> No, because that would be doing the same thing as C++, which 
> Walter and Andrei
> have already rejected. They specifically do _not_ want there to 
> be any
> ambiguity between whether a const ref variable is an lvalue or 
> rvalue. If they
> were willing to make const ref work the same as C++'s const&, 
> then we would
> never have had this problem in the first place. We specifically 
> need something
> other than const ref. The const ref can continue to work as it 
> does now, but
> we'll have a way to get semantics similar to C++'s const& when 
> we want them.

Wow, now this finally sheds some light on this topic. Do you have 
any links regarding their reasoning?
I simply and utterly fail to comprehend the need for a compiler 
to distinguish between a const reference to a named variable and 
a const reference to an unnamed temporary/literal (which the 
compiler is free to allocate wherever it makes most sense). 
Especially since the compiler could simply allocate and name the 
original rvalue as local variable on the caller's stack before 
the function call and hence transform it automatically to an 
lvalue, i.e., do that, what currently most of us have to 
painfully do by hand.
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, November 07, 2012 02:15:26 martin wrote:
> Wow, now this finally sheds some light on this topic. Do you have
> any links regarding their reasoning?

The most recent discussion where Walter and Andrei were part of the discussion 
was here:

http://forum.dlang.org/post/4F84D6DD.5090405@digitalmars.com

A key component of the problem is that conversions cause problems. Also, IIRC 
allowing const ref to take rvalues causes some issues with overloading.

Making some changes to ref with regards to escaping apparently could change
the situation a bit, and there's even some discussion in there of allowing ref
to take rvalues if certain other things in the language are changed, but it's
all up in the air at this point. Certainly, it's not a simple matter of just
making const ref work with rvalues like most of the people coming from C++ want
and expect.

- Jonathan M Davis
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 00:32:04 UTC, martin wrote:
> So we do not really need 'auto ref' for non-templated functions 
> or a new, even more confusing keyword which you, Jonathan, seem 
> to insist on - 'const ref' (or, more elegantly 'in ref') is all 
> we need. We simply want the compiler to automatically declare 
> rvalues passed to 'const ref' parameters as local lvalues - 
> problem solved for the majority of cases. For the remaining few 
> which care about the involved cost for rvalue arguments, allow 
> them to provide a function overload for rvalues (either 
> manually or via 'auto ref' templates) - problem solved 
> completely in my point of view. And that is actually exactly 
> what the thread starter Malte proposes (and I already pointed 
> that out in an earlier post).

 'in ref' may work, but what it implies doesn't quite make sense. 
'auto ref' already being used for templates should be able to 
carry over to functions, however auto in the same section along 
with type declaration may seem a little confusing. Let's glance 
at a few of how they would be called.

//either
void func(int x);
void func(const int x);

//lvalue
void func(ref int x);
void func(const ref int x);

//either? auto ref/in ref
void func(auto ref int x);
void func(const auto ref int x);
void func(in ref int x);

 Assuming auto can't be used to do type referencing the 'const 
auto ref int' seems rather long. alternatively perhaps inout? 
(accepts any type, partially skewed?)

void func(inout ref int x);
void func(const inout ref int x);

 At this point for const it's just as large as the const auto 
ref.. So..

void func(inout ref int x); //mutable
void func(in ref int x);    //const version

void func(out ref int x);   //optional write-only variable

 'out ref int x' could then be legal..  Somehow reminds me of 
zlib's compress utility function that returns how many bytes the 
output buffer used but sometimes you didn't care. So.. if we 
defined and used...


void func(out ref int x) {
  x = 100;
}

int x;
func(x);
assert(x == 100);

func(0);    //0 and null (and legal) basically ignored.
func(null);
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 01:15:27 UTC, martin wrote:
> I simply and utterly fail to comprehend the need for a compiler 
> to distinguish between a const reference to a named variable 
> and a const reference to an unnamed temporary/literal (which 
> the compiler is free to allocate wherever it makes most sense).

Let me be more precise: I don't see why a called function would 
need to know whether a passed const reference is named or unnamed 
at the caller's site. The developer's reasoning for a const 
reference is simply to avoid costly copying of the argument to be 
passed (only applicable for lvalues) which is guaranteed not to 
be modified by the callee. Decorating such a parameter with 
'const ref' seems as logical as it gets (don't pass me a copy of 
the real thing, pass me a reference instead - I'm not going to 
modify it).
The only reason I can think of to distinguish between lvalues and 
rvalues at the callee is the slight performance hit due to 
pointer indirection for rvalues. And that would be addressable by 
preferring by-value-passing of rvalues when selecting between 
function overloads.
November 07, 2012
Re: Const ref and rvalues again...
On Tuesday, 6 November 2012 at 23:37:25 UTC, martin wrote:
>
> void func(T)(in auto ref T m);
>
> This template, as I understand it, gets expanded to:
>
> void func(T)(in ref T m); // for lvalues
> void func(T)(in T m);     // for rvalues
>
> So for non-templated functions, I suggest 2 options:
>
> 1) The previously described auto-templates (identical 'auto 
> ref' semantics), where a function with 'auto ref' parameters is 
> treated as implicit template. This may lead to code-bloating 
> (for larger functions) and/or higher performance for rvalue 
> arguments (rvalues passed to value arguments are moved, not 
> copied; we therefore gain nothing by passing a reference, but 
> incur a slight performance hit due to pointer indirection 
> instead of accessing directly the rvalue on the stack). OR
> 2) Simple under-the-hood temporary lvalue declaration by the 
> compiler (for rvalues passed to 'const ref' parameters) - that 
> would be a handy implementation of the first workaround.
>
> I hope you get my point. :)

What about the case where we want to pass a source argument 
either by reference or as a copy depending on the l/r value 
situation?

eg
void f( ref a );
void f( a );

--rt
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 01:33:49 UTC, Jonathan M Davis 
wrote:
> The most recent discussion where Walter and Andrei were part of 
> the discussion
> was here:
>
> http://forum.dlang.org/post/4F84D6DD.5090405@digitalmars.com

That thread is quite misleading and, I'm sad to say, not very 
useful (rather damaging to this discussion) in my opinion - 
especially because the distinction between rvalue => 'const ref' 
and rvalue => ref is largely neglected, and that distinction is 
of extremely high importance, I can't stress that enough. 
Walter's 3 C++ examples (2 of them invalid anyway afaik) don't 
relate to _const_ references. The implicit type conversion 
problem in that thread isn't a problem for _const_ references, 
just to point out one tiny aspect.
rvalue => ref/out propagation makes no sense imho, as does 
treating literals as lvalues (proposed by Walter iirc). The 
current 'auto ref' semantics also fail to cover the special role 
of _const_ references for rvalues (also illustrated by 
Scarecrow's post).

> Certainly, it's not a simple matter of just making const
> ref work with rvalues like most of the people coming from
> C++ want and expect.

Well I absolutely do _not_ share this point of view. It just 
seems so logical to me. I'm still waiting for a plausible 
argument to prove me wrong. All the required info is in this 
thread, e.g., we covered the escaping issue you mentioned.
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:06:09 UTC, Rob T wrote:
> What about the case where we want to pass a source argument 
> either by reference or as a copy depending on the l/r value 
> situation?
>
> eg
> void f( ref a );
> void f( a );
>
> --rt

I don't get what you mean - that's why the 2 overloads are for 
(you forgot the const/in keyword - beware! :))

void f( in ref T a );
void f( in T a );

rvalue binds to the latter overload (argument not copied, but 
moved directly).
lvalue binds to the first overload (reference).
Works with v2.060.
November 07, 2012
Re: Const ref and rvalues again...
On Tuesday, 6 November 2012 at 23:37:25 UTC, martin wrote:
> 1) The previously described auto-templates (identical 'auto 
> ref' semantics), where a function with 'auto ref' parameters is 
> treated as implicit template. This may lead to code-bloating 
> (for larger functions) and/or higher performance for rvalue 
> arguments (rvalues passed to value arguments are moved, not 
> copied; we therefore gain nothing by passing a reference, but 
> incur a slight performance hit due to pointer indirection 
> instead of accessing directly the rvalue on the stack). OR
> 2) Simple under-the-hood temporary lvalue declaration by the 
> compiler (for rvalues passed to 'const ref' parameters) - that 
> would be a handy implementation of the first workaround.

Please discard option 1, I'm afraid it creates too much confusion 
and was not well thought through. The objective was to expand 
'auto ref T' to either 'in ref T' for lvalues or 'in T' for 
rvalues (i.e., only for const parameters!), but then its caption 
would be horribly misleading (and something like 'in auto ref' 
would be way too ambiguous).
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:45:15 UTC, martin wrote:
> Please discard option 1, I'm afraid it creates too much 
> confusion and was not well thought through. The objective was 
> to expand 'auto ref T' to either 'in ref T' for lvalues or 'in 
> T' for rvalues (I.e., only for const parameters!), but then its 
> caption would be horribly misleading (and something like 'in 
> auto ref' would be way too ambiguous).


 Maybe a very simple change/addition; Like perhaps @ref? 
(Attribute ref, Alternate ref, auto ref.. All sorta fit for it's 
meaning).

 So...

 void func1(ref int x);  //D lvalue-only ref
 void func2(@ref int x); //works like c++'s ref

 Seems fairly easy to tell apart, and still leaves const-ness as 
an option.
November 07, 2012
Re: Const ref and rvalues again...
On Wednesday, 7 November 2012 at 02:58:57 UTC, Era Scarecrow 
wrote:
> Maybe a very simple change/addition; Like perhaps @ref? 
> (Attribute ref, Alternate ref, auto ref.. All sorta fit for 
> it's meaning).
>
> So...
>
> void func1(ref int x);  //D lvalue-only ref
> void func2(@ref int x); //works like c++'s ref
>
> Seems fairly easy to tell apart, and still leaves const-ness as 
> an option.

Afaik C++ doesn't allow rvalues to be passed to _mutable_ 
references (T&), only to const references, making perfect sense 
imo. I really do not see the point for an additional syntax for 
C++-like const references (const T&) which would also take 
rvalues.
Please give me an example where you want to pass an rvalue to a 
_mutable_ reference parameter. I would simply continue to 
disallow that, since that would mean that changes to the 
referenced rvalue would not be visible for the caller (a 
temporary/literal is changed - how could someone possibly want 
that?).
1 2 3 4 5 6 7 8 9
Top | Discussion index | About this forum | D home