std::packaged_task not breaking promises on destruction?
Asked Answered
R

2

16

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?

Remanent answered 10/9, 2014 at 10:8 Comment(0)
I
11

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

Ipsus answered 10/9, 2014 at 10:40 Comment(3)
So did I read those links correctly, this will not be fixed in VS 2013?Remanent
@EmilyL. I'd say very unlikely. According to Q5 in the FAQ section of this page, they backport bugfixes only rarely.Ipsus
Great, the studio we bought is barely a year old and they are already leaving us in a pinch. sigh Thanks for the confirmation. Accepting this answer as the links put the final confirmation on my suspicions.Remanent
C
7

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

Capacity answered 10/9, 2014 at 10:19 Comment(1)
Fully agreed. An abandoned future (i.e. the return value in this case) is the situation for a broken_promise.Klansman

© 2022 - 2024 — McMap. All rights reserved.