Search code examples
c++c++11visual-studio-2013futurepackaged-task

std::packaged_task not breaking promises on destruction?


I'm encountering something very weird when using packaged tasks. When reading ~packaged_task I get the impression that if a std::packaged_task is destroyed before it is executed, the promise will be broken and an attempt to get the result from the future should throw std::future_error.

However, on Visual Studio 2013 this doesn't seem to be the case. Take this following code:

#include <iostream>
#include <future>
#include <functional>

int main() {
    std::future<int> f;
    {
        std::packaged_task<int()> task([](){return 3; });
        f = task.get_future();
    }
    std::cout<<f.get()<<std::endl;
    return 0;
}

I'm expecting to get an std::future_error on f.get() but instead it blocks, waiting for the packaged task to be executed.

Trying another compiler: http://ideone.com/Wt0WOc does indeed throw a std::future_error("Broken promise")...

Am I seeing a bug in Visual Studio 2013 or have I missed something?


Solution

  • You are correct. ~packaged_task() abandons the shared state (§30.6.9.1 [futures.task.members]/p9), which means, if the shared state is not ready, storing an exception object of type future_error with error condition of broken_promise, then making the shared state ready; and then releasing the shared state (§30.6.4 [futures.state]/p7).

    This is a known bug that will be fixed in the next version of Visual Studio, which is likely to come out some time in 2015. It's also fixed in the CTP, but it's a pretty bad idea to use that for production code...