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

How to parse a date string into a c++11 std::chrono time_point or similar?
0xC0000005: Access violation reading location 0x00000000 hashfunc [closed]
Objects modified when they are passed to a function as arguments in C++
How to send message FROM Chrome extension TO Native app?
Qt: distinguish between drag from same or other window
Dynamically allocated string array, then change it's value?
Efficiency in a C++ function?
using nested std::array to create an multidimensional array without knowing dimensions or extents until runtime
How to create a C/C++ Library and Put them into Xcode for iOS?
Applying some filter on my accelerometer data - Windows phone 8, C++
distribute a number of zeros anywhere in a grid
VDS (Virtual Disk Service) COM interface notifications - callback (sink) invoked only during unregister (Unadvise)
SQL Server and OLE DB Consumer: pointer to IUnknown interface of a Rowset Object
Assign values based on variable name in a string
_HAS_EXCEPTIONS=1 vs _HAS_EXCEPTIONS=0
Creating callbacks using callfuncND_selector in Cocos2d-X

Categories

HOME
rstudio
java-ee
lucene
openerp
firebase-authentication
encryption
data-warehouse
autodesk-forge
web-crawler
fiware
houndify
windows-forms-designer
google-cloud-endpoints
android-gradle
distributed-database
soundcloud
c#-3.0
worksheet-function
playframework-2.5
jasperserver
jestjs
android-toast
interaction
ninja
row-number
hudson
markup
netbeans-7.3
spring-statemachine
konvajs
zillow
couchbase-view
indexof
messagebox
ctype
byte
grunt-connect-proxy
multiple-domains
reactive-streams
appery.io
meta-tags
fixture
retrieve-and-rank
maximo-anywhere
simplemodal
grunt-string-replace
rethinkdb-python
getelementsbyclassname
pwd
tivoli-identity-manager
tinyxml2
jsdoc3
shodan
libtool
optional
data-transfer
windows-firewall-api
nested-function
parrot
compass
xlconnect
jquery-ui-resizable
http-accept-header
xlet
dynamic-ip
ekeventstore
wave
wunderlist
ironscheme
date-arithmetic
google-text-to-speech
mysql-num-rows
componentone
mooc
arbitrary-precision
nxt-python
xcode6.1
out
webproxy
maptiler
spn
graphml
mib
xadisk
readelf
java-service-wrapper
nested-queries
memory-profiling
ext-direct
testdriven.net
www-mechanize
validationsummary
dynamic-css
id-generation
laconica
resource-cleanup
pia

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