On 01/04/2013 10:48 AM, deadalnix wrote:
> On Friday, 4 January 2013 at 16:47:38 UTC, Jonathan M Davis wrote:

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

Still, there is no semantic difference. I know this issue from C++. At first I had embraced it but I am not so sure anymore. The language is getting out of its way to protect the programmer. A language like C++ that gives so much freedom to do many other unsafe things...

Constructors and functions do not affect objects alone. However frowned upon, a function that is called on an S may have side-effects that are beyond the object itself. If foo() does s.bar() and S.bar has a side-effect, I wouldn't care about the changes on the rvalue object itself.

So, I think C++ could have allowed binding rvalues to references to non-const. I don't think I would be bothered with that. If I had fooled myself occasionally, so be it.

>> Where there's no real difference is
>>
>> foo(S(2));
>> foo(funcThatReturnsS());

Agreed.

>>
>
> This may not have a storage :
> foo(funcThatReturnsS());

I don't see that. funcThatReturnsS returns an S, which must have a storage as well.

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

Getting back to this issue: So what? I have one more bug in my code.

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

I agree with all of that. (Although, the French grammar rule of that space before the question mark is hurting my eyes! :p)

>> 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),

I hope D's 'auto ref' solution solves this issue once and for all. :)

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

I don't see that. There is storage for the rvalue returned from funcThatReturnsBar() as well, no?

struct Bar {
    uint i;

    this(uint foo) {
        import std.stdio;
        writeln(&this);
    }
}

void foo(Bar bar)
{}

Bar funcThatReturnsBar()
{
    return Bar(1);
}

void main() {
    foo(Bar(0));
    foo(funcThatReturnsBar());
}

That program prints two addresses for me:

7FFFF1076290
7FFFF1076298

Ali

Reply via email to