WTF did happen with struct constructor and ref in 2.061 ?

Jonathan M Davis jmdavisProg at gmx.com
Fri Jan 4 08:46:46 PST 2013


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());

and yet previously, if foo accepted its argument by ref, the first compiled and 
the second didn't. In both cases, you're dealing with a temporary. They 
shouldn't be treated any differently from one another, and as both are 
temporaries, both should be treated as rvalues.

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.

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. 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.

- Jonathan M Davis


More information about the Digitalmars-d mailing list