I am interested whether this is forced by standard and whether it is violated by some compiler. My observation is that:
- Visual Studio 2015/2017 (with /EHsc): stack in the throw() function is not unwound (d-tors are not called), but exception exits function and is being caught by try/catch. No std::terminate is called.
gcc (6.3.0), stack in throw() function is unwound but then std::terminate is called (exception cannot be cought by try/catch). But with 7.0 (current HEAD), no stack is being unwound, std::termiante is called immediately. Actually gcc 7.0 even warns of this :
warning: throw will always call terminate() [-Wterminate]
forNoExceptFunctionWithObj2()
. It makes throw() behave as noexcept(true).clang, in all versions I have checked unwinds function stack (objects d-tors are called), and then std::terminate is called.
#include <iostream>
#include <string>
#include <vector>
struct TestDataWithoutNoexcept {
TestDataWithoutNoexcept() {
std::cout << __FUNCTION__ << "\n";
}
~TestDataWithoutNoexcept() {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept(TestDataWithoutNoexcept const & rhs) {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept(TestDataWithoutNoexcept && rhs) {
std::cout << __FUNCTION__ << "\n";
}
TestDataWithoutNoexcept& operator=(TestDataWithoutNoexcept const& rhs) {
std::cout << __FUNCTION__ << "\n";
}
};
void NoExceptFunctionWithObj1() noexcept {
TestDataWithoutNoexcept test;
throw std::runtime_error("NoExceptFunctionWithObj1 ex.");
}
void NoExceptFunctionWithObj2() throw() {
TestDataWithoutNoexcept test;
throw std::runtime_error("NoExceptFunctionWithObj2 ex.");
}
int main()
{
// Now lets see whether stack is being unwound when exception is thrown in noexcept versus throw() function.
std::cout << "\n See how dtors are called in noexcept or throw() functions\n";
try {
//NoExceptFunctionWithObj1();
}
catch (std::runtime_error& ex) {
std::cout << ex.what();
}
try {
NoExceptFunctionWithObj2();
}
catch (std::runtime_error& ex) {
std::cout << "\nShouldn't this be shown? : " << ex.what();
}
}