void f(int &x) try {
throw 10;
}
catch (const int &i)
{
x = i;
}
int main() {
int v = 0;
f(v);
}
The value of v after f() is
called is 10.A function try block on main() does not catch exceptions thrown in destructors of objects with static storage duration, or constructors of namespace scope objects.
The following example throws an exception from a destructor of a static object. This example is intended to show that the exception in ~B() is caught by the function try block of main(), but that the exception in ~A() is not caught because ~A() is executed after main() has completed.
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
class A {
public: ~A() { throw E("Exception in ~A()"); }
};
class B {
public: ~B() { throw E("Exception in ~B()"); }
};
int main() try {
cout << "In main" << endl;
static A cow;
B bull;
}
catch (E& e) {
cout << e.error << endl;
}
In main Exception in ~B()The run time will not catch the exception thrown when object cow is destroyed at the end of the program.
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { }
};
namespace N {
class C {
public:
C() {
cout << "In C()" << endl;
throw E("Exception in C()");
}
};
C calf;
};
int main() try {
cout << "In main" << endl;
}
catch (E& e) {
cout << e.error << endl;
}
The following is the output of the above example: In C()The compiler will not catch the exception thrown when object calf is created.
In a function try block's handler, you cannot have a jump into the body of a constructor or destructor.
A return statement cannot appear in a function try block's handler of a constructor.
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { };
};
class B {
public:
B() { };
~B() { cout << "~B() called" << endl; };
};
class D : public B {
public:
D();
~D() { cout << "~D() called" << endl; };
};
D::D() try : B() {
throw E("Exception in D()");
}
catch(E& e) {
cout << "Handler of function try block of D(): " << e.error << endl;
};
int main() {
try {
D val;
}
catch(...) { }
}
The following is the output of the above example: ~B() called Handler of function try block of D(): Exception in D()When the function try block's handler of D() is entered, the run time first calls the destructor of the base class of D, which is B. The destructor of D is not called because val is not fully constructed.
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { };
};
class A {
public:
A() try { throw E("Exception in A()"); }
catch(E& e) { cout << "Handler in A(): " << e.error << endl; }
};
int f() try {
throw E("Exception in f()");
return 0;
}
catch(E& e) {
cout << "Handler in f(): " << e.error << endl;
return 1;
}
int main() {
int i = 0;
try { A cow; }
catch(E& e) {
cout << "Handler in main(): " << e.error << endl;
}
try { i = f(); }
catch(E& e) {
cout << "Another handler in main(): " << e.error << endl;
}
cout << "Returned value of f(): " << i << endl;
}
The following is the output of the above example: Handler in A(): Exception in A() Handler in main(): Exception in A() Handler in f(): Exception in f() Returned value of f(): 1

#include <cstdio>
using std::printf;
int global_argc;
struct A{
int _x;
A();
A(int);
};
A::A(int x):_x((printf("In A::A(int) initializer for A::_x.\n"),x)){
printf("In A::A(int) constructor body.\n");
if(global_argc % 2 !=0){
printf("Will throw.\n");
throw 0;
}
printf("Will not throw.\n");
}
A::A() try:A((printf("In A::A() initializer for delegating to A::A(int).\n"),42)){
printf("In A::A() function-try-block body.\n");
}
catch(...){
printf("In catch(...) handler for A::A() function-try-block.\n");
}
int main(int argc, char **argv){
printf("In main().\n");
global_argc = argc;
try{
A a;
printf("Back in main().\n");
}
catch(...){
printf("In catch(...) handler for try-block in main().\n");
}
return 0;
}
The example can produce different output depending on
how many arguments are passed on the invocation of the resulting program.
With an even number of arguments, the exception is thrown. The output
is:In main(). In A::A() initializer for delegating to A:A(int). In A::A(int) initializer for A::_x. In A::A(int) constructor body. Will throw. In catch(...) handler for A::A() function-try-block. In catch(...) handler for try-block in main().With an odd number of arguments, there is no exception thrown. The output is:
In main(). In A::A() initializer for delegating to A::A(int). In A::A(int) initializer for A::_x. In A::A(int) constructor body. Will not throw. In A::A() function-try-block body. Back in main().
For more information, see Delegating constructors (C++0x)
