| Thread overview | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 19, 2009 temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
What's a rationale behind an issue described bug 2621? http://d.puremagic.com/issues/show_bug.cgi?id=2621 Why isn't it allowed anymore? It broke quite a lot of my code. And while it is fixable by doing auto tmp = someFunctionThatRetunsStruct(); someMethodThatAcceptsStructByReference(tmp); it looks ugly and unnecessary. | ||||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | Denis Koroskin wrote:
> What's a rationale behind an issue described bug 2621?
> http://d.puremagic.com/issues/show_bug.cgi?id=2621
>
> Why isn't it allowed anymore?
>
> It broke quite a lot of my code. And while it is fixable by doing
>
> auto tmp = someFunctionThatRetunsStruct();
> someMethodThatAcceptsStructByReference(tmp);
>
> it looks ugly and unnecessary.
Yeah, I was recently caught by this when moving some code over to D2, thinking I'd take advantage of some const refs. I was quite surprised when my code wouldn't compile. Consider:
struct Foo
{
int x;
Foo opAdd(const ref Foo lhs)
{
Foo f = {x + lhs.x};
return f;
}
ref Foo opAddAssign(const ref Foo lhs)
{
x += lhs.x;
return f;
}
}
Given Foo a, b and c, the following fails to compile:
c += a + b;
The work around is to add an overridden opAddAssign that takes a non-ref foo. Not pretty, especially when dealing with numerous methods. Rather defeats the purpose of const ref parameters, does it not? And it's far from intuitive, particularly when coming from C++.
| |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | On Sun, Apr 19, 2009 at 8:41 AM, Denis Koroskin <2korden@gmail.com> wrote:
> What's a rationale behind an issue described bug 2621? http://d.puremagic.com/issues/show_bug.cgi?id=2621
>
> Why isn't it allowed anymore?
>
> It broke quite a lot of my code. And while it is fixable by doing
>
> auto tmp = someFunctionThatRetunsStruct();
> someMethodThatAcceptsStructByReference(tmp);
>
> it looks ugly and unnecessary.
>
Wow, that's pretty dumb. I use that a lot too.
| |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | Denis Koroskin wrote:
> What's a rationale behind an issue described bug 2621? http://d.puremagic.com/issues/show_bug.cgi?id=2621
>
> Why isn't it allowed anymore?
>
> It broke quite a lot of my code. And while it is fixable by doing
>
> auto tmp = someFunctionThatRetunsStruct();
> someMethodThatAcceptsStructByReference(tmp);
>
> it looks ugly and unnecessary.
To resolve this, let's consider two suspicions I have:
1) People use 'ref' for speed. Fairly obvious. I do it too. :)
2) People don't use 'out' for speed. This seems obvious, since 'out' does _more_ work than 'ref'.
2a) 'out' has stronger semantic meaning than 'ref'.
Because of this, I recommend allowing temporaries to be passed to 'ref' parameters, but not 'out' parameters. That way, you can still use 'out' to implement extraneous return values.
| |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Denis Koroskin | On Sun, Apr 19, 2009 at 8:41 AM, Denis Koroskin <2korden@gmail.com> wrote:
> What's a rationale behind an issue described bug 2621? http://d.puremagic.com/issues/show_bug.cgi?id=2621
>
> Why isn't it allowed anymore?
>
> It broke quite a lot of my code. And while it is fixable by doing
>
> auto tmp = someFunctionThatRetunsStruct();
> someMethodThatAcceptsStructByReference(tmp);
>
> it looks ugly and unnecessary.
I just thought of something. Why the hell should we keep C++'s "const ref" anyway? When you use "const ref" it means you want it to be read-only and fast to pass large structures. But why should the onus of passing value types byref be on the programmer? Why not make it so "const valuetype" will pass byval for smaller values and byref for larger, completely freeing the programmer from this tedious crap? It's not something that I care about, and the threshold of byval vs. byref differs from platform to platform.
Let's nip this in the bud right now. A const value type parameter should automatically decide whether to pass by reference or not.
| |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote: > Let's nip this in the bud right now. A const value type parameter should automatically decide whether to pass by reference or not. Suggested change: an 'in' parameter should be either by-value or by-reference at the compiler's discretion. There needs to be a way to explicitly specify pass-by-value for those few cases where there is a semantic difference between by-value and by-reference. -- Rainer Deyke - rainerd@eldwood.com | |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | Jarrett Billingsley wrote:
> On Sun, Apr 19, 2009 at 8:41 AM, Denis Koroskin <2korden@gmail.com> wrote:
>> What's a rationale behind an issue described bug 2621?
>> http://d.puremagic.com/issues/show_bug.cgi?id=2621
>>
>> Why isn't it allowed anymore?
>>
>> It broke quite a lot of my code. And while it is fixable by doing
>>
>> auto tmp = someFunctionThatRetunsStruct();
>> someMethodThatAcceptsStructByReference(tmp);
>>
>> it looks ugly and unnecessary.
>
> I just thought of something. Why the hell should we keep C++'s "const
> ref" anyway? When you use "const ref" it means you want it to be
> read-only and fast to pass large structures. But why should the onus
> of passing value types byref be on the programmer? Why not make it so
> "const valuetype" will pass byval for smaller values and byref for
> larger, completely freeing the programmer from this tedious crap?
> It's not something that I care about, and the threshold of byval vs.
> byref differs from platform to platform.
>
> Let's nip this in the bud right now. A const value type parameter
> should automatically decide whether to pass by reference or not.
I suggested that change. First let me clarify that the suggestion above cannot work. Due to aliasing, leaving it to the compiler to choose between by-value and by-reference leads to functions breaking when the size of the object changes, which is unacceptable.
struct S { int x; ... }
void foo(const S s1, ref S s2)
{
s1.x = 5;
s2.x = 6;
}
S s;
foo(s, s); // messed up
Now onto why ref was disallowed to bind to an rvalue. This is because some functions take things by ref intending to change them. Passing an rvalue is in such cases a bug.
I agree there are functions that only want to use ref for speed purposes. I suggested Walter to use ref? for those. ref? means it could be an rvalue or an lvalue.
Andrei
| |||
April 19, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 19/04/2009 22:52, Andrei Alexandrescu wrote:
> Jarrett Billingsley wrote:
>> On Sun, Apr 19, 2009 at 8:41 AM, Denis Koroskin <2korden@gmail.com>
>> wrote:
>>> What's a rationale behind an issue described bug 2621?
>>> http://d.puremagic.com/issues/show_bug.cgi?id=2621
>>>
>>> Why isn't it allowed anymore?
>>>
>>> It broke quite a lot of my code. And while it is fixable by doing
>>>
>>> auto tmp = someFunctionThatRetunsStruct();
>>> someMethodThatAcceptsStructByReference(tmp);
>>>
>>> it looks ugly and unnecessary.
>>
>> I just thought of something. Why the hell should we keep C++'s "const
>> ref" anyway? When you use "const ref" it means you want it to be
>> read-only and fast to pass large structures. But why should the onus
>> of passing value types byref be on the programmer? Why not make it so
>> "const valuetype" will pass byval for smaller values and byref for
>> larger, completely freeing the programmer from this tedious crap?
>> It's not something that I care about, and the threshold of byval vs.
>> byref differs from platform to platform.
>>
>> Let's nip this in the bud right now. A const value type parameter
>> should automatically decide whether to pass by reference or not.
>
> I suggested that change. First let me clarify that the suggestion above
> cannot work. Due to aliasing, leaving it to the compiler to choose
> between by-value and by-reference leads to functions breaking when the
> size of the object changes, which is unacceptable.
>
> struct S { int x; ... }
> void foo(const S s1, ref S s2)
> {
> s1.x = 5;
> s2.x = 6;
> }
>
> S s;
> foo(s, s); // messed up
>
> Now onto why ref was disallowed to bind to an rvalue. This is because
> some functions take things by ref intending to change them. Passing an
> rvalue is in such cases a bug.
>
> I agree there are functions that only want to use ref for speed
> purposes. I suggested Walter to use ref? for those. ref? means it could
> be an rvalue or an lvalue.
>
>
> Andrei
that does not compile.
you tried to change a *const* struct...
| |||
April 20, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote:
> Jarrett Billingsley wrote:
>> On Sun, Apr 19, 2009 at 8:41 AM, Denis Koroskin <2korden@gmail.com> wrote:
>>> What's a rationale behind an issue described bug 2621?
>>> http://d.puremagic.com/issues/show_bug.cgi?id=2621
>>>
>>> Why isn't it allowed anymore?
>>>
>>> It broke quite a lot of my code. And while it is fixable by doing
>>>
>>> auto tmp = someFunctionThatRetunsStruct();
>>> someMethodThatAcceptsStructByReference(tmp);
>>>
>>> it looks ugly and unnecessary.
>>
>> I just thought of something. Why the hell should we keep C++'s "const
>> ref" anyway? When you use "const ref" it means you want it to be
>> read-only and fast to pass large structures. But why should the onus
>> of passing value types byref be on the programmer? Why not make it so
>> "const valuetype" will pass byval for smaller values and byref for
>> larger, completely freeing the programmer from this tedious crap?
>> It's not something that I care about, and the threshold of byval vs.
>> byref differs from platform to platform.
>>
>> Let's nip this in the bud right now. A const value type parameter
>> should automatically decide whether to pass by reference or not.
>
> I suggested that change. First let me clarify that the suggestion above cannot work. Due to aliasing, leaving it to the compiler to choose between by-value and by-reference leads to functions breaking when the size of the object changes, which is unacceptable.
>
> struct S { int x; ... }
> void foo(const S s1, ref S s2)
> {
> s1.x = 5;
> s2.x = 6;
> }
>
> S s;
> foo(s, s); // messed up
>
> Now onto why ref was disallowed to bind to an rvalue. This is because some functions take things by ref intending to change them. Passing an rvalue is in such cases a bug.
>
> I agree there are functions that only want to use ref for speed purposes. I suggested Walter to use ref? for those. ref? means it could be an rvalue or an lvalue.
Aside from the real issue at hand, ref? nees some other notation. Using a question mark here makes it look appalling, and kludgy. One also feels it's an interrogative of some kind.
| |||
April 20, 2009 Re: temporary objects are not allowed to be pass by ref anymore | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Andrei Alexandrescu wrote:
...
> Now onto why ref was disallowed to bind to an rvalue. This is because some functions take things by ref intending to change them. Passing an rvalue is in such cases a bug.
>
> I agree there are functions that only want to use ref for speed purposes. I suggested Walter to use ref? for those. ref? means it could be an rvalue or an lvalue.
>
>
> Andrei
Since passing by const ref cannot change the parameter, is it possible to allow that for rvalues?
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply