std :: фьючерсы и исключения

Учитывая следующий исходный код

#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;
}

}

Я ожидаю, что программа ответит Valid: 0, При использовании g ++ 6.2.0 это так. Однако, используя MS VS2015 версии 14.0.25431.01 с обновлением 3, ответ Valid: 1, Состояние будущего не считается недействительным после того, как исключение было передано в основной поток. Это ошибка или я сталкиваюсь с неопределенным поведением здесь?

6

Решение

Я, кажется, ошибка.

В соответствии с std::future::get документация , valid() должен вернуться false после звонка get,

Любое общее состояние освобождается. valid() является false после вызова этого метода.

Окунемся в реализацию VC ++ getтам есть ошибка:

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

в принципе, _Retreived также должен быть установлен в true если _Exception держит exception_ptr, к моменту броска эта переменная никогда не устанавливается. кажется, что когда они проверяли это, они не проверяли готовое будущее,
только для неготового будущего, потому что последний не покажет эту ошибку.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]