• Create Account

### #ActualServant of the Lord

Posted 01 November 2012 - 09:22 PM

I've posted my opinions on it in this thread (I don't want to copy+paste the large-ish post).

That's about return values, not parameters, though.

The thread is about return values primarily, but my post talks about both parameters and return values.

Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so?

I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.

I was under the impression from the Going Native 2012 videos that it is very likely to use move semantics in that situation, but I was getting confused between lvalues and rvalues. If it was an rvalue, such as an unnamed temporary, it would use move semantics instead of copying (if a move constructor exists for that type). I don't know if it's guaranteed that it will, but I think it would be if the argument type had the proper move constructor.

std::vector<std::string> result = GetStuff(std::vector<std::string>(1000, "very large string containing alot of data");

In this case, since the vector as an argument is an unnamed temporary, my possibly flawed understanding is that it will be guaranteed to be moved instead of copied (if a move constructor exists). Further, my (again: possibly-flawed) understanding that GetStuff(), without RVO, would create a temporary, and then the temporary would be moved into 'result'.

However, you could use std::move() to tell the compiler to move the lvalue and get the same effect: std::move() would take the lvalue and return it as a rvalue, allowing GetStuff() to use a move-constructor for its parameter.

std::vector<std::string> veryLargeVector;
veryLargeVector.resize(2000, "very large string containing alot of data");
std::vector<std::string> result = GetStuff(std::move(veryLargeVector));

It seems all of this would depend on the class being passed around to actually implement move constructors though (which std::vector does).

Where I'm getting my impressions from:

GoingNative 2012 - STL11: Magic && Secrets (2012 - Particularly 35 minutes into the video)

I haven't read the actual standard, despite having the PDF draft on my computer.

tl;dr: I was getting confused between lvalues and rvalues, but you can explicitly get the same result if you use std::move() and the type has a move constructor defined. Whether or not a compilers would automaticly detect it (which I recall hearing somewhere, but have no proof of, and it wouldn't be guaranteed), an explicit std::move() should guarantee it.

### #1Servant of the Lord

Posted 01 November 2012 - 09:19 PM

I've posted my opinions on it in this thread (I don't want to copy+paste the large-ish post).

That's about return values, not parameters, though.

The thread is about return values primarily, but my post talks about both parameters and return values.

Regarding your post on that other thread, you claim that the compiler will use move semantics in a situation where a caller passes a (local?) value as a function parameter and doesn't use that value afterwards. I see how the compiler has a chance to optimize in this situation, but does the standard actually guarantee the compiler will do so?

I don't remember reading about such a thing before. It seems like a potentially very expensive and difficult thing for the compiler to detect reliably under all conditions.

I was under the impression from the Going Native 2012 videos that it is very likely to use move semantics in that situation, butI was getting confused between lvalues and rvalues. If it was an rvalue, such as an unnamed temporary, it would use move semantics instead of copying (if a move constructor exists for that type). I don't know if it's guaranteed that it will, but I think it would be if the argument type had the proper move constructor.
std::vector<std::string> result = GetStuff(std::vector<std::string>(1000, "very large string containing alot of data");
In this case, since the vector as an argument is an unnamed temporary, my possibly flawed understanding is that it will be guaranteed to be moved instead of copied (if a move constructor exists). Further, my (again: possibly-flawed) understanding that GetStuff(), without RVO, would create a temporary, and then the temporary would be moved into 'result'.

However, you could use std::move() to tell the compiler to move the lvalue and get the same effect: std::move() would take the lvalue and return it as a rvalue, allowing GetStuff() to use a move-constructor for its parameter.
std::vector<std::string> veryLargeVector;
veryLargeVector.resize(2000, "very large string containing alot of data");
std::vector<std::string> result = GetStuff(std::move(veryLargeVector));

It seems all of this would depend on the class being passed around to actually implement move constructors though (which std::vector does).

Where I'm getting my impressions from:

GoingNative 2012 - STL11: Magic && Secrets (2012 - Particularly 35 minutes into the video)

I haven't read the actual standard, despite having the PDF draft on my computer.

tl;dr: I was getting confused between lvalues and rvalues, but you can explicitly get the same result if you use std::move() and the type has a move constructor defined. Whether or not a compilers would automaticly detect it (which I recall hearing somewhere, but have no proof of, and it wouldn't be guaranteed), an explicit std::move() should guarantee it.

PARTNERS