1

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));
        t.detach();
        ...
        // 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;
    }
}

Here string s 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 move is potentially dangerous, while the other question is about whether actively prohibits copy elision or let compiler decide.

Community
  • 1
  • 1
athos
  • 6,120
  • 5
  • 51
  • 95

2 Answers2

2

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

Mateusz Drost
  • 1,171
  • 10
  • 23
  • I thought `move` means "stealing memory location" so no need to copy? Is this an STL specific implementation ? – athos Nov 18 '16 at 04:12
  • 1
    `move` rather mean "steal memory location if it is useful or whatever you want but leave this object in valid state". After move string internal data pointer could be null and that is valid if destructor does not try to free null pointer. – Mateusz Drost Nov 18 '16 at 04:23
2

This is not a problem.

Move semantics moves the internal value of a variable not the variable itself. So you still have a separate destination string to the source string.

The whole exercise works ostensibly like a copy except that afterwards the source object has changed its value to an unknown quantity.

It is still a valid object (of unknown value) and will be properly destroyed when the stack unwinds.

Galik
  • 47,303
  • 4
  • 80
  • 117
  • I thought `move` means "stealing memory location" so no need to copy? – athos Nov 18 '16 at 04:12
  • 1
    @athos Well *move* is about stealing the internal value which may or may not amount to a memory location. From the outside though, it just looks (and behaves) like a copy except the object that was moved from has (possibly) changed its value. – Galik Nov 18 '16 at 04:41