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