Suppose I have a function returning by value
S f();
and I call it like that:
auto s = f();
If copy-constructor of S
throws, and return some_s;
inside f
is surrounded by try-catch block,
is it guaranteed that the exception will be captured
inside f
rather than being thrown on the call site?
I realize that auto s = f();
is subject to mandatory copy elision as of C++17, so there is (at most) one call to copy-constructor of S
. But is it guaranteed to happen inside f
from the point of view of exception handling?
Tests in gcc, clang, mingw and msvc indicate that this is indeed so (the code is below). What bothers me is that
- it is opposite to exceptions from copy-constructors of functions parameters, that are handled on the call site
- it seems odd that return does not actually transfer control out of a function
In any case, some quotes from the standard will be appreciated 😉
Here is the code I used for testing
#include<iostream>
struct S{
S(const S &){
throw "Oops";
}
S(int) noexcept {}
};
S f(){
static/*to avoid RVO*/ S stat(7);
try{
return stat;
}catch(const char *what){
std::cerr << "still in function after failed-return" << std::endl;
}
return S(7);// mandatory copy-elision (c++17);
}
int main()
try{
auto s = f();// mandatory copy-elision (c++17);
}catch(...){
std::cerr << "Exception from main..." << std::endl;
}
1