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?
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...
I think it's a bug, the standard says ~packaged_task
abandons the shared state, which means that if it isn't ready yet it should store a broken_promise
exception and make the state ready, just as you expect.
Full disclosure: your ideone.com test uses GCC and I implemented GCC's <future>
so I might be biased when I say its behaviour is correct ... but I think it is still correct ;-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With