c++


Why not capture the already propagating exception in `std::promise::~promise`


Say you have the following code
void func(std::promise<int> prom) {
try {
auto promise = std::promise<int>{std::move(prom)};
// .. do stuff
throw std::runtime_error{"something went wrong"};
} catch (...) {
// cleanup and dont bother with the promise
}
}
auto promise = std::promise<int>{};
auto future = promise.get_future();
std::thread{[promise = std::move(promise)] {
func(std::move(promise));
}}.detach();
try {
cout << future.get() << endl;
} catch (std::exception& exc) {
cerr << exc.what() << endl;
}
What is the reason behind not catching the exception that is propagating when the promise is destroyed and re-propagating the same exception on the future end? Why is a broken promise exception always thrown in such a situation?
I just feel like its natural to have the same exception re-propagate on the future end.
To clarify what I meant, in addition to having the set_exception() method, I thought the destructor calling set_exception(std::current_exception()) could be a good idea
Upon catching the exception and storing a reference to it, the destructor would then rethrow the exception
A destructor has no exception to catch or rethrow. I think the logic you want is:
If the destructor detects that it's being called as part of stack unwinding; and
it would otherwise store a future_error with broken_promise in the shared state, then
it stores current_exception() in the shared state instead.
Let's ignore the fact that until C++17 you can't portably detect if you are being called as part of stack unwinding; implementations have access to "magic" things that mere mortals don't.
First, you are sharing the exception object across threads silently, with all the attendant risks of data races. Sharing things across threads is hard enough without the standard library stabbing you in the back.
Second, an exception on the producer's side may well be meaningless for the consumer. In many cases the consumer doesn't care if the producer failed to produce a value because of a network error or the phase of the moon. All it cares is that the promise was broken.
You propose that std::promise's destructor catch active exceptions and store them.
What does do_stuff return under your proposal?
int do_stuff(std::future& f) {
std::vector<int> alice;
std::promise bob;
f = bob.get_future();
throw 7;
alice.push_back(42);
return alice[0];
}
what does do_stuff return? The 7 thrown was catught in ~promise, but that bypasses the return value calculation.
I see nothing but insanity down this path.
Exceptions are already a come-from, but at least they are structured come-from. Your proposal requires unstructured catching and would make program flow of exceptions completely beyond anyone's ability to understand.
If it simply duplicated the exception, in general you aren't allowed to do that? You can store a (smart) pointer to them, but not a copy.

Related Links

gsoap does not serve over both ipv4 and ipv6
Qt Charts - How to display a specific point value on x and y axis?
std::move return and input reference argument
building curl with mingw32 and linking lib file to VS 2015
How to show std::vector in QT properly?
How does compiler(GCC) deal with the access control for C++?
Passing a matrix as a parameter by function call operator overloading
Flip model swap chain doesn't acknowledge menu bar
sdbm hash on multiple bytes simultaneously
C++ VS Debugger diverting behaviour?
How to make istringstream more efficient? [duplicate]
Using tag-dispatch to implement or-combinable flags
Wt in Visual Studio 2015
sort a list of numbers from highest to lowest
Changing a functions variable through another C++ function
Using C++ implementation of OpenSSL to decrypt data

Categories

HOME
perl
java-ee
local-storage
jsoup
masonry
junit
owasp
authorization
google-cloud-kms
etcd
uiviewcontroller
mips32
graph-algorithm
opentsdb
directshow
worksheet-function
spark-dataframe
face-recognition
logstash-grok
prefix
cpu-registers
file-permissions
packet-capture
btrfs
amazon-lightsail
indexoutofrangeexception
formsets
rubinius
akka-stream
android-appbarlayout
wijmo5
jquery-ui-autocomplete
induction
handbrake
spamassassin
winrt-xaml
regedit
shieldui
moa
model-driven
azure-sql-server
webos
laravel-excel
ranorex
cics
safe-browsing
orika
sqlitestudio
silent-installer
cakephp-3.3
snobol
ember-cli-mirage
rollbar
unite.vim
stdio
self-referencing-table
code-collaborator
htsql
python-wheel
reportviewer2008
kindle
parrot
timedelta
android-6.0.1
episerver-6-r2
singularitygs
stompjs
wx
msbuildcommunitytasks
html5builder
sql-agent-job
dotdotdot
setlocale
httplib
unassigned-variable
sqr
django-1.7
xcode6.1
galera
teamcity-7.1
sandbox-solution
qglviewer
interlacing
divshot
apprequests
array-formulas
customvalidator
gwt-2.5
git-add
dynamic-content
assetslibrary
flotr
expandoobject
eda
django-generic-views
mkstorekit
platform-independence
pdc2008

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App