Std :: Futures and Exception

Given the following source code

#include <thread> #include <future> #include <iostream> #include <string> #include <chrono> int main() { auto task = std::async(std::launch::async, [] { std::this_thread::sleep_for(std::chrono::milliseconds(1000)); throw std::runtime_error("error"); }); try { while (task.wait_for(std::chrono::seconds(0)) !=std::future_status::ready) { std::cout << "Not ready: " << std::endl; } task.get(); } catch (const std::exception& e) { std::cout << "Valid: " << task.valid() << std::endl; } } 

I expect the program to respond using Valid: 0 . Using g ++ 6.2.0, it is. However, using MS VS2015 Version 14.0.25431.01 Update 3, Valid: 1 answer Valid: 1 . The state of the future is not invalid after the exception has spread to the main thread. Is this a bug or am I encountering undefined behavior here?

+5
source share
1 answer

I think I was wrong.

According to std::future::get documentation , valid() should return false after calling get .

Any shared state issued. valid() false after calling this method.

Digging a bit into the implementation of VC ++ get , there is an error:

 virtual _Ty& _Get_value(bool _Get_only_once) { // return the stored result or throw stored exception unique_lock<mutex> _Lock(_Mtx); if (_Get_only_once && _Retrieved) _Throw_future_error( make_error_code(future_errc::future_already_retrieved)); if (_Exception) _Rethrow_future_exception(_Exception); _Retrieved = true; _Maybe_run_deferred_function(_Lock); while (!_Ready) _Cond.wait(_Lock); if (_Exception) _Rethrow_future_exception(_Exception); return (_Result); } 

in principle, _Retreived should also be set to true if _Exception contains exception_ptr . by the time of throwing this variable is never set. it seems that when they tested it, they did not experience preparedness for the future, only for the future of unpreparedness, since the latter would not show this error.

+1
source

Source: https://habr.com/ru/post/1265129/


All Articles