I have some library (actually the tbb library compiled with a different compiler), throwing an exception before main() proper started. Is there a way to catch that?
int main() { std::cout << "Hello World" << std::endl; }
gives
terminating with unexpected foreign exception
Abort (core dumped)
if I link against said library (which is not used in this example, but in other code it will be).
Generally speaking, it is not possible in standard C++ to catch an exception that is thrown during construction of a global variable (which is outside scope of any function).
I believe the closest possibility is to use a function-try-block for the body of the constructor of the static.
class MyStatics
{
public:
MyStatics();
private:
X x; // construction may fail
Y y; // construction may fail
// etc
};
static MyStatics all_my_statics;
MyStatics::Mystatics() : x(), y() // implement using a function try block
try
{
if (some_condition) throw some_exception(); // construction may even fail here
}
catch (SomeException &)
{
// handler for SomeException
}
If an exception is thrown during construction of all_my_statics, then any fully-constructed members of it will be destructed (i.e. MyStatics members do not exist within such a catch block).
Within the catch block there aren't many options, after reporting about the caught exceptions. The main options will be;
throw (or rethrow) an exception (since the construction of MyStatics has failed). That exception will cause std::terminate() to be called.
terminate the program in some other way deemed to be "cleaner".
It is not a good idea to swallow an exception thrown during construction of a static since the program (e.g. within main()) will have no indication that statics it relies on have not been properly constructed.
It is more usual to place the static object within a function
X &the_x()
try
{
static X thing;
return thing;
}
catch (Whatever &)
{
// handler
}
Bear in mind that every call of the_x() will attempt to construct thing until one of them succeeds (i.e. if an exception is thrown the first time, the second call will attempt to construct thing, etc). However, if the first call of the_x() within the program can be identified and exceptions from it caught (i.e. wrap it in a try/catch) it is not necessary to catch exceptions from subsequent calls - since, if the first call doesn't throw, the construction of thing has succeeded, and it will not be constructed again.
I found this interesting source. It bases his construction on std::terminate functionality
He proposes to use a sort of global try...catch (you can't continue anymore to run, but you can act depending of exception):
[[noreturn]] void onTerminate() noexcept
{
if( auto exc = std::current_exception() ) {
// we have an exception
try{
rethrow_exception( exc ); // throw to recognize the type
}
catch( MyException const& exc ) {
// additional action
}
catch( MyOtherException const& exc ) {
// additional action
}
catch( std::exception const& exc ) {
// additional action
}
catch( ... ) {
// additional action
}
}
std::_Exit( EXIT_FAILURE );
}
and to register this caller when an exception occurred, earliest possible:
const auto installed{ std::set_terminate(&handler) };
int main() {
// run...
}
But you have to know that you can't be sure that std::set_terminate will be called before any instanciation.
Related
I have a class, call it A, whose constructor takes some input arguments, and may throw an exception if they are incompatible for constructing that object. In my main code, I construct an object of type A as follows:
A my_obj(arg1,arg2,arg3);
and use it. Obviously if the constructor fails and throws the exception, the execution of the program will be terminated after printing out an 'unhandled exception' message.
I, however, would like to give the user more information in this case and tell him/her why the exception has been thrown. So, I need a way to catch the exception.
To this end, one possibility is to enclose the whole code, starting from the declaration of my_obj till the end of the program in a try block and catch the exception afterwards:
try {
A my_obj(arg1, arg2, arg3);
// ...
// about 100 other lines of code being executed if my_obj is created properly
}
catch (std::exception& e) {
// print a user-friendly error message and exit
}
But this looks to me a bit of an 'overkill'. Specifically since no other exceptions are thrown in the remaining 100 lines. Is there any other nicer way to accomplish this?
If the constructor throws, you don't have an object. std::optional<> is a type that means "We might not have an object here".
template <typename T, typename ... Args>
std::optional<T> try_make(Args&& ... args)
{ try {
return make_optional(std::forward(args...));
} catch (...) {
return {};
} }
Then
auto my_obj = try_make<A>(arg1,arg2,arg3);
if (my_obj) {
// about 100 other lines of code being executed if my_obj is created properly
}
One possibility would be the usage of a pointer (better use a smart pointer such as an unique_ptr as in below code). You would leave the unique_ptr empty, call the constructor in the try block and move the pointer into the unique_ptr. After that your other code executes. Surely you have to check for a valid pointer with the operator bool of unique_ptr in a simple if statement.
To simplify the usage of my_obj a reference is taken: A& my_obj_ref = *my_obj;.
std::unique_ptr<A> my_obj;
try {
my_obj = std::move(std::unique_ptr<A>(new A(arg1, arg2, arg3));
}
catch (std::exception& e) {
// print a user-friendly error message and exit
}
if (my_obj) { // needed if your exception handling doesn't break out of the function
A& my_obj_ref = *my_obj;
// ...
// about 100 other lines of code being executed if my_obj is created properly
}
Remember that this way would allocate your object on the heap instead of the stack.
You can abstract the object construction into a function that catches the exception:
template<typename... Args>
A make_a(Args&&... args) {
try {
return A(std::forward(args)...);
}
catch (std::exception& e) {
// print a user-friendly error message and exit
...
std::exit(EXIT_FAILURE);
}
}
// ... in the actual code:
A my_obj = make_a(arg1, arg2, arg3);
The above makes use of the fact that your program is exiting if construction fails. If the requirement were to continue running, the function could return std::optional<A> (or its boost equivalent if you don't have access to C++17.)
You have several options here, depending on how you want control to continue if the construction fails.
If you want to exit the function by throwing an exception, then you don't need to do anything, you can let the A construction exception propagate up.
If you want to exit by either throwing a different exception, or by performing some actions before letting the A construction exception propagate, then use a factory function (perhaps a lambda) that performs those actions, e.g.:
auto a_factory(T x, U y) -> A // or use perfect forwarding
{
try { return A(x, y); }
catch(...) {
log("constructing A failed...");
throw other_exception();
}
}
// ...
A my_obj = a_factory(x, y);
If you want to exit by returning a value, then you could still use the above method, but wrap the calling function in another function that catches expected exceptions and returns a value.
Or you could use the optional (below) or unique_ptr (as covered by other answers) technique, but executing a return statement from the catch block.
If you want to continue execution without a valid A, then you can do:
std::optional<A> opt_my_obj;
try
{
A temp(...args...);
opt_my_obj.swap(temp);
} catch(...)
{
// handling, you could return from the function here
}
// At this point you can test `if ( opt_my_obj )` to branch the flow.
// When you're at a point where you have verified the object exists, you
// can enable normal object syntax by writing:
A& my_obj = *opt_my_obj;
If you have several objects in your function that need this consideration, I would tend to suggest the version of having the whole function wrapped in a try...catch that can handle all the different exceptions.
I tend to do it simple: Throw the human readable message. This strategy works well when there is no choice, and usually, there isn't. There is a catch though, you want exception handling to be reasonably robust, so I package the message inside a std::array<char,4096> truncating if necessary and remembering the zero-terminator (I know that this could blow the stack but it should be fine if we are not in a recursive function), and throw that.
Example:
try
{
Options opts(argv);
SomeResource resource(opts.someParameter());
//...More actions that could throw
}
catch(const std::array<char,4096>& errmessage) //Or rather some other type that contains the message.
{
fprintf(stderr,"Error: %s\n",errmessage.data());
return -1; //Or any non-zero value
}
return 0;
Pros:
Quick to implement new constructors for new classes since there is one exception class only, that will works for everything
You will pick up any system messages right from the source
Cons:
Lack of context: The message will have to say something like "It was not possible to open the file foo: No such file or directory.". Without telling the user what the root cause for the exception. This problem is inherited from the exception model and cannot be solved without treating exceptions as glorified error codes
If you want to branch on exception content, you must parse the message, but I find this rarely needed. Possibly in the context of a compiler, but that would print that message anyway foo:54:1: Error: bar is not a baz.
Is it possible to throw an exception and catch it without using a try block ?
ex:
int main()
{
throw 1;
catch(int){
std::cerr << "caught exception\n";
}
return 0;
}
According to my experience, you have to use try and catch block in a combination. Here if any error occur in the try block then only it is passed to the catch block. Thus if there is no try block then it won't know where to look for the error. Thus they need to be used in combination. I am not sure in C++ but in Java you can use catch block in singly if you extend the class to throwable.
There is a slight difference in the behavior of program control flow during an exception in flight. try-catch blocks hopefully brings the program back to the usual control flow.
When an exception is thrown at any point in the program. Normal program control flow halts. The program control flow now goes through the runtime's mechanism for exception handling. This is different from what is normal. For the normal, destructors for automatic storage always runs when control flow reaches the end of scope (lifetime) "}". For exceptions in flight, they run earlier than normal
Consider this (note the comments);
MyClass foo(){
{
MyClass c;
c.call(balhhh); //assuming this throws
// (1)
....
return c;
}
void bar(){
std::map<K,V> mp;
auto c = foo();
// (2)
mp.insert(c);
....
}
When you call bar, we can see how control flow is per-maturely leaves foo() at // (1), no other code after // (1) is executed within the scope of foo(), the same thing happens when foo() has been unwound, and we are now at // (2)
This happens throughout stack-unwinding process, And this recursively unwinds all functions... until we are back to main() where std::terminate is called.
Now, with a try-catch block, the compiler generates code that suspends that early exit behavior after program has moved to a catch block (in search for a matching handler), and if the exception is handled, control flow goes back to normal.
Consider:
MyClass foo()
try {
MyClass c;
c.call(balhhh); //assuming this throws
// (1)
....
return c;
}
catch(...){
...
}
void bar(){
std::map<K,V> mp;
auto c = foo();
// (2)
mp.insert(c);
....
}
Now, when the exception leaves, control flow leaves the norm at // (1) to search for the handler in the associated catch, if the exception was handled, the program goes back to the normal control flow. Code after // (2) will execute now...
As you can see from the explanation, try-catch blocks are the only way as dictated by C++ standards, to restore normal program control flow after an exception is thrown.
int main()
{
throw 1; //fine, program control leaves the whole of main at this point.
catch(int){ //illegal, like using an else block without an if
std::cerr << "caught exception\n";
}
return 0;
}
Even if the above code was legal, throw means control will leave the whole of the enclosing scope at the throw site.
How can I protect myself from using object which isn't fully created when using exceptions?
Should I catch in constructor ? Or maybe it's bad practice ? If I'll catch in constructor object will be created.
#include <stdio.h>
class A
{
public:
A()
{
try {
throw "Something bad happened...";
}
catch(const char* e) {
printf("Handled exception: %s\n", s);
}
// code continues here so our bad/broken object is created then?
}
~A()
{
printf("A:~A()");
}
void Method()
{ // do something
}
};
void main()
{
A object; // constructor will throw... and catch, code continues after catch so basically we've got
// broken object.
//And the question here:
//
//* is it possible to check if this object exists without catching it from main?
// &object still gives me an address of this broken object so it's created but how can I protect myself
// from using this broken object without writing try/catch and using error codes?
object.Method(); // something really bad. (aborting the program)
};
The language itself has no concept of an object being "invalid" in any detectable way.
If the exception indicates that a valid object can't be created, then it shouldn't be handled within the constructor; either rethrow it, or don't catch it in the first place. Then the program will leave the scope of the object being created, and it won't be possible to incorrectly access it.
If that isn't an option for some reason, then you'll need your own way to mark the object as "invalid"; perhaps set a boolean member variable at the end of the constructor to indicate success. This is flaky and error-prone, so don't do it unless you've got a very good reason.
If the object is in an invalid state when a certain exception is thrown, then I would let the exception unwind the call stack so the caller can be notified (and therefore react) to such things.
However, if the exception is one you can recover from, it may be worth trying to do so depend on your application. Make sure you use something like a logger or even simply stderr to indicate this is happening though.
I am going to suggest a first iteration of doing something more like this:
try {
throw "Something bad happened...";
}
catch(const std::exception e) {
cerr << e.what () << endl ; // Better off in the main
throw ;
}
Two things here:
Unless your exception handler handles the exception, it should throw.
Always use exception classes based upon std::exception to that you can always find out what the problem was as shown above.
Hello to all and sorry for my english!
How can I do the title above?
For example, I have a class contains a some functions that can throw exceptions:
class cl {
public:
void f1();
void f2();
};
void cl::f1()
{
// throw exception
}
void cl::f2()
{
// throw exception
}
I need to handle them.
Are there any other method to handle exceptions (that throws in my class) in one place of the code except code like this:
void cl::f1()
{
try
{
// throw exception
}
catch (...)
{
// handling
}
}
void cl::f1()
{
try
{
// throw exception
}
catch (...)
{
// handling
}
}
or this:
int main()
{
cl c;
try
{
f1();
f2();
}
catch(...)
{
// handling
}
}
?
Thanks in advance!
Are there any other method to handle exceptions (that throws in my
class) in one place of the code except code like this:
In my opinion you would typically only handle an exception when:
You can remedy it i.e do something about it e.g allow the user to select a different file.
You can add additional information.
For the latter case, it would mean throwing a new exception (possible of different type) from the handler.
If neither of the above hold, let it propagate to a level where it can be handled. In your case, I would not have a try/catch within f1 and f2, but only at the callsite (in main).
You might ask whether one cannot(should not) do certain cleanup work in the catch handler. I personally have never found this to be necessary if/when one uses the stack/scope to clean up see RAII. I/we usually have one catch handler per thread at the highest level, and this simply performs logging. We catch (and use exceptions) for runtime errors mostly. For logic errors we use assert (even in release mode), but this can be (and have been) debated often.
This is super basic but I can't find the answer anywhere. There's lots of posts out there about throwing and catching, but what actually happens if I throw from function1 and then call function1 from function2 but don't catch it, does that mean it just gets rethrown to the caller of function2? Judging from the following I'd say yes, but I wanted to get a solid guru-like answer before I soldier on and assume:
#include <iostream>
void function1()
{
throw 1;
}
void function2()
{
function1();
}
int main()
{
try
{
function2();
}
catch(...)
{
std::cout << "caught!";
return 0;
}
return 0;
}
Output:
caught!
Yes, that's how exceptions work. When an exception is thrown, it is caught by the topmost function in the call stack that has a handler for that exception in the scope of execution. Since you are going back to a function lower in the stack, some variables in the scope of the functions in the upper stack frames need to get out of scope, and therefore their destructors are called. This is called stack unwinding. It is really nice to combine that and RAII (lookup RAII if you don't know what that is). However, If any destructor throws an exception during stack unwinding, then it is bad and the std::terminate function will be called. Typically your program will then end (and this is why you are always advised to write non-throwing destructors).
From cppreference.com:
Once the exception object is constructed, the control flow works
backwards (up the call stack) until it reaches the start of a try
block, at which point the parameters of the associated catch blocks
are compared with the thrown expression to find a match. If no match
is found, the control flow continues to unwind the stack until the
next try block, and so on. If a match is found, the control flow jumps
to the matching catch block (the exception handler), which executes
normally.
As the control flow moves up the call stack, destructors are invoked
for all objects with automatic storage duration constructed since the
corresponding try-block was entered, in reverse order of construction.
If an exception is thrown from a constructor, destructors are called
for all fully-constructed non-static non-variant members and base
classes. This process is called stack unwinding.
Since function2() and function1() don't catch the exception it will propagate up the call stack until it is caught by the first suitable handler which you have in main(). Local objects destructors are being called along the way which is called stack unwinding. If you didn't have a suitable handler the C++ runtime would call unexpected() built-in function that would call abort() and terminate the program.
Yes, but it doesn't get "rethrown" - simply, when you throw an exception it will walk the call stack until it can find a catch block that can handle it; this is one of the most important "selling points" of exceptions.
If no suitable handler is found, std::terminate is called and your program terminates abnormally (notice that in this case it's not guaranteed that destructors will be called).
does that mean it just gets rethrown to the caller of function2?
No, it's not rethrown; the original throw sends it as far up the call stack as necessary until a handler is found. In this case, there's no handler in function1 or function2, so it ends up in the handler in main.
If it's not caught at all, and tries to leave main, then the program will terminate. (There are ways to change that behaviour, but that's not particularly relevant to this question).
Consider the following program:
#include <iostream>
void function1()
{
try
{
throw 1;
}
catch(...)
{
std::cout << "Exception caught in function1." << std::endl;
throw 1;
}
}
void function2()
{
try
{
function1();
}
catch(...)
{
std::cout << "Exception caught in function2." << std::endl;
throw 1;
}
}
int main()
{
try
{
function2();
}
catch(...)
{
std::cout << "Exception caught in main." << std::endl;
}
return 0;
}
Its output is
Exception caught in function1.
Exception caught in function2.
Exception caught in main.
You could throw without any try and catch block. For example,
std::string &someClass::operator[](unsigned position) {
// try {
if (position <= length && position >= 0) {
//return string at that position;
}else{
throw ("out of range");
}
}
In this case, the function checks if the position is within the dynamic array length. Otherwise, it throws a string which will tell the user the position they chose was out of bounds. So there are ways to use a throw statement without a try and catch block (but try and catch are used together, cannot exclude one).