athos athos - 5 months ago 33
C++ Question

is it ok to return a local variable by move?

I'm reading Nicolai M. Josuttis's 2nd edition of "The C++ Standard Library" covering C++11 , where in Chapter 18: Concurrency, page 969 and 970 give a sample program:

// concurrency/promise1.cpp
#include <thread>
#include <future>
#include <iostream>
#include <string>
#include <exception>
#include <stdexcept>
#include <functional>
#include <utility>
void doSomething (std::promise<std::string>& p)
try {
// read character and throw exceptiopn if ’x’
std::cout << "read char (’x’ for exception): ";
char c = std::cin.get();
if (c == ’x’) {
throw std::runtime_error(std::string("char ")+c+" read");
std::string s = std::string("char ") + c + " processed";
p.set_value(std::move(s)); // store result
catch (...) {
p.set_exception(std::current_exception()); // store exception

int main()
try {
// start thread using a promise to store the outcome
std::promise<std::string> p;
std::thread t(doSomething,std::ref(p));
// create a future to process the outcome
std::future<std::string> f(p.get_future());
// process the outcome
std::cout << "result: " << f.get() << std::endl;
catch (const std::exception& e) {
std::cerr << "EXCEPTION: " << e.what() << std::endl;
catch (...) {
std::cerr << "EXCEPTION " << std::endl;

is a local variable but moved to return.

However, as programs quited calltree level by level, the stack memory will be release. Would this be a problem when call stack unwinds?

Note: this question is different from c++11 Return value optimization or move? : this question is about
is potentially dangerous, while the other question is about whether actively prohibits copy elision or let compiler decide.


Unless otherwise specified, all standard library objects that have been moved from are placed in a valid but unspecified state. Valid means it can be safely destroyed (e.g on stack unwinding). In your example s is not returned but stored in promise but if it was returned in normal way return s; compiler could implicitly call return move(s);.