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

Reply via email to