Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The last (in lexical order) copy of an object must be a move #18995

Open
dlangBugzillaToGithub opened this issue Jun 1, 2015 · 4 comments
Open

Comments

@dlangBugzillaToGithub
Copy link

Andrei Alexandrescu (@andralex) reported this on 2015-06-01T04:31:46Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=14638

CC List

Description

Consider (also http://dpaste.dzfl.pl/87e95af25781):

struct S1
{
    this(this) { assert(0); }
}

struct S2
{
    @disable this(this);
}

void fun(S1 s)
{
    gun(s);
}

void gun(S1 s)
{
}

void hun(S2 s)
{
    iun(s);
}

void iun(S2 s)
{
}

void main()
{
    fun(S1());
    hun(S2());
}

This code creates an S1 and an S2 as rvalues and passes them by value into functions. These functions in turn forward the values to other functions, also by value, after which they make no more use of the values.

If a conversion to an rvalue is the last (statically determined) operation on a value in the lexical scope of a variable, then that copy should count as a move. That should be guaranteed, not an optimization.

This rule would automatically enable a lot of sensible code to work with noncopyable values.  This matter is a semi-blocker for std.allocator because most allocators are noncopyable.

BTW this does not need to go into guessing the last dynamic use. For example:

void hun(S2 s)
{
    iun(s); // last dynamic use
    if (false)
    {
        writeln(s); // last static use
    }
}

In this case, the call to iun() may create a copy even though an analysis shows the last static use can never happen. Eliding the last dynamic copy may be implemented as an optimization. Checking for @disable should still be inserted regardless of the optimization.
@dlangBugzillaToGithub
Copy link
Author

issues.dlang (@jmdavis) commented on 2015-06-01T14:00:03Z

So, basically, you want RVO to be guaranteed to occur rather than it being considered an optimization (and thus being optional)?

@dlangBugzillaToGithub
Copy link
Author

issues.dlang (@jmdavis) commented on 2015-06-01T14:04:44Z

Oh, wait. No, this is not just RVO. You're not even returning in the example. Clearly, I paid too much attention to the text and not the example. Not enough sleep, I guess...

@dlangBugzillaToGithub
Copy link
Author

issues.dlang (@jmdavis) commented on 2015-06-01T14:13:59Z

It's my understanding (though I could be wrong) that the

void main()
{
    fun(S1());
    hun(S2());
}

part at least is guaranteed to do a move, since you're dealing with temporaries. I would have expected the rest of it to do moves as well like you're requesting, but I don't remember how guaranteed it's supposed to be. Clearly, the compiler doesn't seem to think that it's guaranteed though, since it's not doing it.

Regardless, I agree with this. We need to make it so that moves are guaranteed where we can for both performance reasons and for noncopyable objects (and the noncopyable objects pretty much throw it in your face when it doesn't do a move).

However, I don't understand what you mean by dynamic and static uses. Is a dynamic use one that may or may not be the last one hit depending on what occurs after it, whereas a static use is guaranteed to be the last use if it's hit?

@dlangBugzillaToGithub
Copy link
Author

andrei (@andralex) commented on 2015-06-01T15:26:07Z

(In reply to Jonathan M Davis from comment #3)
> However, I don't understand what you mean by dynamic and static uses. Is a
> dynamic use one that may or may not be the last one hit depending on what
> occurs after it, whereas a static use is guaranteed to be the last use if
> it's hit?

Static is as you read the code in lexical order, dynamic is as it actually gets executed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant