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