WTF did happen with struct constructor and ref in 2.061 ?
deadalnix
deadalnix at gmail.com
Fri Jan 4 10:48:41 PST 2013
On Friday, 4 January 2013 at 16:47:38 UTC, Jonathan M Davis wrote:
> On Friday, January 04, 2013 13:12:52 js.mdnq wrote:
>> can you show an example of such a bug? I assume you mean that a
>> "struct literal" ends up being a local object and a ref to it
>> can
>> easily become invalid?(in your example this is not possible
>> inside main). But your example basically contradicts what you
>> say.
>>
>> There is no semantic difference between
>>
>> S s = S(2); foo(s)
>>
>> and
>>
>> foo(S(2));
>
> There's a _huge_ difference between those two. In the first
> case, you have a
> variable which exists beyond the end of the function call. In
> the second, you
> have temporary which is destroyed as soon as the statement has
> completed.
> Where there's no real difference is
>
> foo(S(2));
> foo(funcThatReturnsS());
>
This may not have a storage :
foo(funcThatReturnsS());
This MUST have a storage (as this storage is passed to the ctor) :
foo(S(2));
So it is in fact different.
> Also, it's completely nonsensical for a function which is
> supposed to be
> taking its argument by ref to take temporaries. A function
> takes its argument
> by ref so that it can mutate it, and if it accepts rvalues,
> then you lose the
> changes, because you're not dealing with a variable that lasts
> beyond the
> statement that the function call is in.
>
A function can take ref argument for performance reasons. A
function caller may not care about reading the changes.
Yes, if it for performance, auto ref should be used, but why in
the first place a breaking change have been made BEFORE auto ref
is sorted out ? Now it is like saying this is incorrect, here is
the correct way. Ha, BTW, the correct way isn't implemented yet
so we did break your code in unfixable way.
> If the issue is that someone wants the function to avoid making
> copies of the
> argument if it's not necessary, then that's what auto ref is
> for (and why the
> discussion how to implement that for non-templated functions is
> so important),
> and anyone who wants that is going to want it for
> foo(funcThatReturnsS()) just
> as much as they want it for foo(S(2)), making it so that ref
> doesn't solve
> their problem anyway (not to mention, in both of those cases,
> the ref is
> completely unnecessary, because if the function doesn't use
> ref, a move should
> be done rather than a copy, meaning that having foo(S(2)) work
> where foo
> accepts by ref doesn't save you from any copies anyway).
>
> The fact that struct literals have been treated as lvalues is
> just plain
> buggy.
struct Bar {
uint i;
this(uint foo) {
import std.stdio;
writeln(&this);
}
}
void main() {
Bar(0);
}
> There should be _zero_ difference between how a struct literal
> is
> treated and how the return value of a function is treated. Both
> are
> temporaries and should be treated as such.
>
Code above show there is.
> - Jonathan M Davis
More information about the Digitalmars-d
mailing list