digitalmars.D - R-values and const ref
- Eldar Insafutdinov (6/6) Sep 09 2010 A while back dmd stopped allowing rvalues as ref function arguments. I
- bearophile (4/5) Sep 09 2010 From what I have seen D is built on different principles, so I doubt tha...
- Steven Schveighoffer (13/23) Sep 09 2010 auto ref is supposed to handle that. However, I think it only works on ...
- Eldar Insafutdinov (4/4) Sep 09 2010 I agree that auto ref may be a better option here, but I still see no re...
- Steven Schveighoffer (8/14) Sep 09 2010 Yes, I forgot that you are allowed to overload via ref. That would make...
- dsimcha (9/24) Sep 09 2010 After Bug 4843 (the one I posted this morning about overloading ref vs. ...
- Andrei Alexandrescu (6/30) Sep 09 2010 There's no need to map auto ref to two functions. It's only about
- Max Samukha (19/21) Sep 15 2010 That forces us to provide multiple overloads, each matching one of the
- Andrei Alexandrescu (3/17) Sep 09 2010 Indeed, auto ref must work with non-templates.
- Steven Schveighoffer (5/23) Sep 09 2010 Hm... how is that possible? The generated code must surely be different...
- dsimcha (21/27) Sep 09 2010 FWIW, if you can't use templates and auto ref, there is a (slightly verb...
- dsimcha (3/6) Sep 09 2010 ...except that I just realized it's broken for structs.
A while back dmd stopped allowing rvalues as ref function arguments. I entirely understand why it was done, but the same restriction applies to the ref const function parameters. This causes a lot of pain and at the moment makes me use pass-by-value parameters(most notably when using structs). C++ doesn't have any problem with const ref and rvalues. Can we please restore this behavior for const ref?
Sep 09 2010
Eldar Insafutdinov:Can we please restore this behavior for const ref?From what I have seen D is built on different principles, so I doubt that will change. Bye, bearophile
Sep 09 2010
On Thu, 09 Sep 2010 06:08:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:A while back dmd stopped allowing rvalues as ref function arguments. I entirely understand why it was done, but the same restriction applies to the ref const function parameters. This causes a lot of pain and at the moment makes me use pass-by-value parameters(most notably when using structs). C++ doesn't have any problem with const ref and rvalues. Can we please restore this behavior for const ref?auto ref is supposed to handle that. However, I think it only works on templates. The thing is, when you pass an rvalue by reference, it's more expensive than passing it by value. If passed by value, since it's an rvalue, the compiler knows that it no longer is needed elsewhere, so it can just store it on the stack in the place it will be passing it. I still think the design needs some work, and there are some compiler annoyances that can't be helped (like the compiler complaining that opEquals must take const ref T) that make it impossible to write correct code. -Steve
Sep 09 2010
I agree that auto ref may be a better option here, but I still see no reason to disallow it. It is a performance issue, not a safety one. And as you said this only works for templates, virtual functions are out of the game here. PS. opEquals issue is very annoying, indeed.
Sep 09 2010
On Thu, 09 Sep 2010 11:24:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:I agree that auto ref may be a better option here, but I still see no reason to disallow it. It is a performance issue, not a safety one. And as you said this only works for templates, virtual functions are out of the game here. PS. opEquals issue is very annoying, indeed.Yes, I forgot that you are allowed to overload via ref. That would make sense for virtual functions. The problem with allowing const ref rvalues is then you are not *able* to make a better performing function, because rvalues match against const ref as well as the non-ref version. -Steve
Sep 09 2010
== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleOn Thu, 09 Sep 2010 11:24:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:After Bug 4843 (the one I posted this morning about overloading ref vs. non-ref w/ structs) is fixed, it might be a good idea to allow auto ref for non-templated functions as shorthand for a ref function plus a non-ref function that binds to rvalues and forwards to the ref function. On the other hand this might be too much special casing just to save a little typing. It also might not fly w/ Walter and other people who care about low-level/ABI stuff because it breaks the idea that, unless something is explicitly a template, one function at source level should map to one function at the binary level.I agree that auto ref may be a better option here, but I still see no reason to disallow it. It is a performance issue, not a safety one. And as you said this only works for templates, virtual functions are out of the game here. PS. opEquals issue is very annoying, indeed.Yes, I forgot that you are allowed to overload via ref. That would make sense for virtual functions. The problem with allowing const ref rvalues is then you are not *able* to make a better performing function, because rvalues match against const ref as well as the non-ref version. -Steve
Sep 09 2010
On 9/9/10 10:43 CDT, dsimcha wrote:== Quote from Steven Schveighoffer (schveiguy yahoo.com)'s articleThere's no need to map auto ref to two functions. It's only about relaxing the checking for rvalue parameters. The idea will "go" with Walter because it simply is a misunderstanding between design and implementation. AndreiOn Thu, 09 Sep 2010 11:24:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:After Bug 4843 (the one I posted this morning about overloading ref vs. non-ref w/ structs) is fixed, it might be a good idea to allow auto ref for non-templated functions as shorthand for a ref function plus a non-ref function that binds to rvalues and forwards to the ref function. On the other hand this might be too much special casing just to save a little typing. It also might not fly w/ Walter and other people who care about low-level/ABI stuff because it breaks the idea that, unless something is explicitly a template, one function at source level should map to one function at the binary level.I agree that auto ref may be a better option here, but I still see no reason to disallow it. It is a performance issue, not a safety one. And as you said this only works for templates, virtual functions are out of the game here. PS. opEquals issue is very annoying, indeed.Yes, I forgot that you are allowed to overload via ref. That would make sense for virtual functions. The problem with allowing const ref rvalues is then you are not *able* to make a better performing function, because rvalues match against const ref as well as the non-ref version. -Steve
Sep 09 2010
On 09/09/2010 06:26 PM, Steven Schveighoffer wrote:Yes, I forgot that you are allowed to overload via ref. That would make sense for virtual functions.That forces us to provide multiple overloads, each matching one of the possible combinations of rvalue/lvalue arguments. A function with n struct parameters would require 2^n overloads. The only way to avoid the mess is to implement a single function taking all struct arguments by value or use templates, which is unacceptable in the general case. There is also an unspecified part related to default arguments. For example, this compiles: struct S { } S bar() { return S(); } void foo(ref const S s = bar()) { } Is it safe to rely on this feature?
Sep 15 2010
On 9/9/10 6:32 CDT, Steven Schveighoffer wrote:On Thu, 09 Sep 2010 06:08:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:Indeed, auto ref must work with non-templates. AndreiA while back dmd stopped allowing rvalues as ref function arguments. I entirely understand why it was done, but the same restriction applies to the ref const function parameters. This causes a lot of pain and at the moment makes me use pass-by-value parameters(most notably when using structs). C++ doesn't have any problem with const ref and rvalues. Can we please restore this behavior for const ref?auto ref is supposed to handle that. However, I think it only works on templates.
Sep 09 2010
On Thu, 09 Sep 2010 13:03:17 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 9/9/10 6:32 CDT, Steven Schveighoffer wrote:Hm... how is that possible? The generated code must surely be different, so it is in fact a template, even if it's not syntaxed as one. -SteveOn Thu, 09 Sep 2010 06:08:14 -0400, Eldar Insafutdinov <e.insafutdinov gmail.com> wrote:Indeed, auto ref must work with non-templates.A while back dmd stopped allowing rvalues as ref function arguments. I entirely understand why it was done, but the same restriction applies to the ref const function parameters. This causes a lot of pain and at the moment makes me use pass-by-value parameters(most notably when using structs). C++ doesn't have any problem with const ref and rvalues. Can we please restore this behavior for const ref?auto ref is supposed to handle that. However, I think it only works on templates.
Sep 09 2010
== Quote from Eldar Insafutdinov (e.insafutdinov gmail.com)'s articleA while back dmd stopped allowing rvalues as ref function arguments. I entirely understand why it was done, but the same restriction applies to the ref const function parameters. This causes a lot of pain and at the moment makes me use pass-by-value parameters(most notably when using structs). C++ doesn't have any problem with const ref and rvalues. Can we please restore this behavior for const ref?FWIW, if you can't use templates and auto ref, there is a (slightly verbose) solution. DMD apparently allows overloading ref vs. non-ref, so you can write a forwarding function to bind to rvalues. This example compiles and does what it looks like it should. Perhaps the spec needs to be clarified so that people know about this feature and can be sure they're not relying on an obscure implementation bug. import std.stdio; void doStuff(const ref int i) { writeln("Doing stuff by ref."); } // Note that i needs to be const b/c otherwise when forwarding // the non-ref version will look like the better match and // we'll get infinite recursion. void doStuff(const int i) { writeln("Forwarding to ref overload."); doStuff(i); } void main() { doStuff(1); }
Sep 09 2010
== Quote from dsimcha (dsimcha yahoo.com)'s articleFWIW, if you can't use templates and auto ref, there is a (slightly verbose) solution. DMD apparently allows overloading ref vs. non-ref, so you can write a forwarding function to bind to rvalues....except that I just realized it's broken for structs. http://d.puremagic.com/issues/post_bug.cgi
Sep 09 2010