exception handling a constructor - c++

This was an interview question of me.
Surprisingly i never thought of this kinda question to myself.
can we have exception handling inside a constructor c++?
in tense and not thinking much i said "yes we could probably do it in a constructor.lets say we are allocating some memory using new operator to a pointer member and it throws a bad alloc exception,in this way there is a possibility of exceptions being raised"
Then later i thought that constructors can never return a value.So how can an exception inside a constructor caught.now i am asking this to myself!
can anybody pls help me to come out of this confusion?

See this GOTW Constructor Failures question which addresses your query somewhat and goes on to say it is a waste of time.

Constructors don't have a return type,
so it's not possible to use return
codes. The best way to signal
constructor failure is therefore to
throw an exception. If you don't have
the option of using exceptions, the
"least bad" work-around is to put the
object into a "zombie" state by
setting an internal status bit so the
object acts sort of like it's dead
even though it is technically still
alive.
You would catch the exception in the calling code, not within the constructor.
See How can I handle a constructor that fails? for further details (actually, I'd suggest reading the whole page about exception handling, truly enlightening).

Exception handling and return type are completely different. when the program find the exception in constructor, it throws the exception to nearly by catch block [if used] or thrown to caller (main()). in this case, we have catch block in constructor and exception handled by it. Once exception handled, the remaining statement in the constructor/function will be started executing. see the below example,
class A
{
public:
A(){
printf("Hi Constructor of A\n");
try
{
throw 10;
}
catch(...)
{
printf("the String is unexpected one in constructor\n");
}
printf("Hi Constructor of A\n");
}
~A(){
printf("Hi destructor of A\n");
}
};
int main()
{
try{
A obj ;
throw "Bad allocation";
}
catch(int i)
{
printf("the Exception if Integer is = %d\n", i);
}
catch(double i)
{
printf("the Exception if double is = %f\n", i);
}
catch(A *objE)
{
printf("the Exception if Object \n");
}
catch(...)
{
printf("the Exception if character/string \n");
}
printf("Code ends\n");
return 0;
}
This produce Output:
Start: Constructor of A
the String is unexpected one in constructor
End: Constructor of A
Hi destructor of A
the Exception if character/string
Code ends

C++ has try-catch clauses similar to those of other languages. A tutorial can be found online: http://www.cplusplus.com/doc/tutorial/exceptions/
EDIT: example turned into fully working code
#include <iostream>
using namespace std;
class A
{
public:
void f(){
throw 10;
}
A(){
try{
f();
}
catch(int e){
cout << "Exception caught\n";
}
}
};
int main (int argc, const char * argv[])
{
A a;
return 0;
}
This produces output:
Exception caught

Related

Why does an exception thrown in a constructor fully enclosed in try-catch seem to be rethrown?

Considering this silly looking try-catch chain:
try {
try {
try {
try {
throw "Huh";
} catch(...) {
std::cout << "what1\n";
}
} catch(...) {
std::cout << "what2\n";
}
} catch(...) {
std::cout << "what3\n";
}
} catch(...) {
std::cout << "what4\n";
}
its output will surely be (and is) what1, because it will be caught by the closest matching catch. So far so good.
However, when I try to create a constructor for a class that tries to initialise a member via member initialiser list (which will result in an exception being raised) like so:
int might_throw(int arg) {
if (arg < 0) throw std::logic_error("que");
return arg;
}
struct foo {
int member_;
explicit foo(int arg) try : member_(might_throw(arg)) {
} catch (const std::exception& ex) { std::cout << "caught1\n"; }
};
int main() {
try {
auto f = foo(-5);
} catch (...) { std::cout << "caught2\n"; }
}
The output of the program is now:
caught1
caught2
Why is the exception being rethrown here (I assume that it is, otherwise why would two catches fire?)? Is this mandated by the standard or is it a compiler bug? I am using GCC 10.2.0 (Rev9, Built by MSYS2 project).
cppreference has this to say about a function-try-block (which is what we have here):
Every catch-clause in the function-try-block for a constructor must terminate by throwing an exception. If the control reaches the end of such handler, the current exception is automatically rethrown as if by throw.
So there we have it. Your exception is automatically rethrown when the catch on the constructor's member initialization list exits. I guess the logic is that your constructor is deemed to have failed so (after the exception handler in the constructor performs any cleanup, perhaps) the exception is automatically propagated to the caller.
While the other answer gives a great official explanation, there is also a really intuitive way to see why things have to behave this way: Consider the alternative.
I've replaced the int with a string to make the issue obvious, but the same principle applies with arithmetic types as well.
std::string might_throw(const std::string& arg) {
if (arg.length() < 10) throw std::logic_error("que");
return arg;
}
struct foo {
std::string member_;
explicit foo(const std::string& arg) try : member_(might_throw(arg)) {
} catch (const std::exception& ex) { std::cout << "caught1\n"; }
};
int main() {
try {
auto f = foo("HI");
std::cout << f.member_ << "\n"; // <--- HERE
} catch (...) { std::cout << "caught2\n"; }
}
What would be supposed to happen if the exception did not propagate?
Not only did arg never make it to member, but the string's constructor never got invoked at all. It's not even default constructed. Its internal state is completely undefined. So the program would be simply broken.
It's important that the exception propagates in such a way to avoid messes like this.
To pre-empt the question: Remember that the reason initializer lists are a thing in the first place is so that member variables can be initialized directly without having their default constructor invoked beforehand.

Understanding the try-block

I'm studying C++ by 2 months and I'm having some problem with understanding the try-catch block in C++. I'm using the book : programming principles and practice using C++, here is what my book says :
the basic idea of the exceptions is that if a function find is an error that it cannot handle, it does not return normally, instead, it throws an exception indicating what went wrong. Any direct or indirect caller can catch the exception, that is, specify what to do if the called code used throw.
What does "any direct or indirect caller can cacht the exception means ? does the author means the caller of a function or the catch function ?". I'm confused about this, Could you exaplain it to me in simple way ?
Example for indirect call:
Here the exception happens in the called function. But the try catch is placed in the calling function, and not the called function.
#include <iostream>
#include <exception>
using namespace std;
void divideByZero(){
int a = 5;
int b = a / 0;
throw(b);
}
int main()
{
try{
divideByZero();
}
catch (exception& e){
cout<<e.what()<<endl;
}
return 0;
}
Example for direct exception:
Here the exception happens in the functions itself directly, and handled there itself.
#include <iostream>
using namespace std;
int main()
{
try{
int a = 5;
int b = a / 0;
throw(b);
}
catch (exception& e){
cout<<e.what()<<endl;
}
return 0;
}
The above program is used only for illustration and not for any real example, which you are likely to come across when you write a useful program.

When is a function try block useful?

I'm wondering when programmers use function try blocks. When is it useful?
void f(int i)
try
{
if ( i < 0 )
throw "less than zero";
std::cout << "greater than zero" << std::endl;
}
catch(const char* e)
{
std::cout << e << std::endl;
}
int main() {
f(1);
f(-1);
return 0;
}
Output: (at ideone)
greater than zero
less than zero
EDIT: As some people might think that the syntax of function defintion is incorrect (because the syntax doesn't look familiar), I've to say that no its not incorrect. Its called function-try-block. See ยง8.4/1 [dcl.fct.def] in the C++ Standard.
You use it in constructors to catch errors from initializers. Usually, you don't catch those errors, so this is a quite exceptional use.
Otherwise, it is useless: unless I'm proven wrong,
void f() try { ... } catch (...) { ... }
is strictly equivalent to
void f() { try { ... } catch (...) { ... } }
Function try block are useful for me in two contexts.
a) To have a catch all clause around main() allowing to write small utilities without having to worry about local error handling:
int main()
try {
// ...
return 0;
}
catch (...) {
// handle errors
return -1;
}
which is clearly just syntactic sugar for having a try/catch inside main() itself.
b) to handle exceptions thrown by base class constructors:
struct B {
B() { /*might throw*/ }
};
struct A : B {
A()
try : B() {
// ...
}
catch (...) {
// handle exceptions thrown from inside A() or by B()
}
};
Aside from the functional uses mentioned, you can use the function-try-block to save yourself one level of indentation. (Ack, an answer about coding styles!)
Typically you see examples with the function-try-block like so:
void f(/*...*/)
try {
/*...*/
}
catch(/*...*/) {
/*...*/
}
Where the function scope is indented to the same level as if there were no function-try-block. This can be useful when:
you have an 80 character column limit and would have to wrap lines given the extra indentation.
you are trying to retrofit some existing function with try catch and don't want to touch all the lines of the function. (Yeah, we could just use git blame -w.)
Though, for functions that are entirely wrapped with a function-try-block, I would suggest not alternating between some functions using function-try-blocks and some not within the same code base. Consistency is probably more important then line wrapping issues.
:)
Notes regarding how function try blocks operate:
For constructors, a function try block encompasses the construction of data members and base-classes.
For destructors, a function try block encompasses the destruction of data members and base-classes. It gets complicated, but for C++11, you have to include noexcept(false) in the declaration of your destructor (or that of a base/member class) or any destruction exception will result in termination at the conclusion of the catch block. It may be possible to prevent this by putting a return statement in the catch block (but this won't work for constructors).
A catch block in a constructor or destructor must throw some exception (or it will implicitly rethrow the caught exception). It is not legal to simply return (at least in constructor's function catch block). Note, however, that you could call exit() or similar, which might make sense in some situations.
A catch block can't return a value, so it doesn't work for functions returning non-void (unless they intentionally terminate the program with exit() or similar). At least that is what I've read.
The catch block for a constructor-function-try can't reference data/base members since they will have either have 1) not been constructed or 2) been destructed prior to the catch. As such, function try blocks are not useful for cleaning up an object's internal state -- the object should already be completely "dead" by the time you get there. This fact makes it very dangerous to use function try blocks in constructors, since it is difficult to police this rule over time if your compiler(s) don't happen to flag it.
valid (legal) uses
Translating an exception (to a different type/message) thrown during the constructor or it's base/member constructors.
Translating or absorbing and exception thrown during the destructor or it's base/member destructors (destructor etiquette notwithstanding).
Terminating a program (perhaps with a useful message).
Some kind of exception logging scheme.
Syntactic sugar for void-returning functions that happen to need a fully encapsulating try/catch block.
It might be useful if you want to catch exceptions from constructor's initializer.
However, if you do catch exception in constructor that way, you have to either rethrow it or throw new exception (i.e. you cannot just normally return from constructor). If you do not rethrow, it just happens implicitly.
#include <iostream>
class A
{
public:
A()
try {
throw 5;
}
catch (int) {
std::cout << "exception thrown\n";
//return; <- invalid
}
};
int main()
{
try {
A a;
}
catch (...) {
std::cout << "was rethrown";
}
}
Another thing you can use them for is to provide extra data during debugging, in a manner that doesn't interfere with the finished build. I haven't seen anyone else use or advocate it, but it's something I find convenient.
// Function signature helper.
#if defined(_WIN32) || defined(_WIN64)
#define FUNC_SIG __FUNCSIG__
#elif defined(__unix__)
#define FUNC_SIG __PRETTY_FUNCTION__
// Add other compiler equivalents here.
#endif /* Function signature helper. */
void foo(/* whatever */)
#ifdef DEBUG
try
#endif /* DEBUG */
{
// ...
}
#ifdef DEBUG
catch(SomeExceptionOrOther& e) {
std::cout << "Exception " << e.what() << std::endl
<< "* In function: " << FUNC_SIG << std::endl
<< "* With parameters: " << /* output parameters */ << std::endl
<< "* With internal variables: " << /* output vars */ << std::endl;
throw;
}
#endif /* DEBUG */
This would allow you to both obtain useful information while testing your code, and easily dummy it out without affecting anything.

C++ get description of an exception caught in catch(...) block

can I get description of an exception caught by
catch(...)
block? something like .what() of std::exception.
There is one trick you might be able to use:
catch(...) {
handle_exception();
}
void handle_exception() {
try {
throw;
} catch (const std::exception &e) {
std::cout << e.what() << "\n";
} catch (const int i) {
std::cout << i << "\n";
} catch (const long l) {
std::cout << l << "\n";
} catch (const char *p) {
std::cout << p << "\n";
} catch (...) {
std::cout << "nope, sorry, I really have no clue what that is\n";
}
}
and so on, for as many different types as you think might be thrown. If you really know nothing about what might be thrown then even that second-to-last one is wrong, because somebody might throw a char* that doesn't point to a nul-terminated string.
It's generally a bad idea to throw anything that isn't a std::exception or derived class. The reason std::exception exists is to allow everybody to throw and catch objects that they can do something useful with. In a toy program where you just want to get out of there and can't even be bothered to include a standard header, OK, maybe throw an int or a string literal. I don't think I'd make that part of a formal interface. Any exceptions you throw are part of your formal interface, even if you somehow forgot to document them.
That block might catch an int, or a const char*, or anything. How can the compiler possibly know how to describe something when it knows nothing about it? If you want to get information off an exception, you must know the type.
If you know you only throw std::exception or subclasses, try
catch(std::exception& e) {...e.what()... }
Otherwise, as DeadMG wrote, since you can throw (almost) everything, you cannot assume anything about what you caught.
Normally catch(...) should only be used as the last defense when using badly written or documented external libraries. So you would use an hierarchy
catch(my::specialException& e) {
// I know what happened and can handle it
... handle special case
}
catch(my::otherSpecialException& e) {
// I know what happened and can handle it
... handle other special case
}
catch(std::exception& e) {
//I can at least do something with it
logger.out(e.what());
}
catch(...) {
// something happened that should not have
logger.out("oops");
}
Since C++11 you can capture the current exception with a pointer:
std::exception_ptr p; // default initialization is to nullptr
try {
throw 7;
}
catch(...)
{
p = std::current_exception();
}
This behaves like a smart pointer; so long as there is at least one pointer pointing to the exception object it is not destroyed.
Later (maybe even in a different function) you can take action in a similar way to the current top answer:
try {
if ( p )
std::rethrow_exception(p);
}
catch(int x)
{
}
catch(std::exception &y)
{
}
How we have our exceptions implemented is that, we have our own Exception classes, that are all derived from std::exception..
Our exceptions will contain Exception message, Function name, File name and line where exceptions are generated. These are all useful not just to show the Messages but also can be used for logging which helps to diagnose the Exception quite easily. So, we get the entire information about the Exceptions generated.
Remember exceptions are for us to get information about what went wrong. So, every bit of information helps in this regard..
Quoting bobah
#include <iostream>
#include <exception>
#include <typeinfo>
#include <stdexcept>
int main()
{
try {
throw ...; // throw something
}
catch(...)
{
std::exception_ptr p = std::current_exception();
std::clog <<(p ? p.__cxa_exception_type()->name() : "null") << std::endl;
}
return 1;
}

Is there any way to get some information at least for catch(...)?

Is there any way to get at least some information inside of here?
...
catch(...)
{
std::cerr << "Unhandled exception" << std::endl;
}
I have this as a last resort around all my code. Would it be better to let it crash, because then I at least could get a crash report?
No, there isn't any way. Try making all your exception classes derive from one single class, like std::exception, and then catch that one.
You could rethrow in a nested try, though, in an attempt to figure out the type. But then you could aswell use a previous catch clause (and ... only as fall-back).
You can do this using gdb or another debugger. Tell the debugger to stop when any exception is throw (in gdb the command is hilariously catch throw). Then you will see not only the type of the exception, but where exactly it is coming from.
Another idea is to comment out the catch (...) and let your runtime terminate your application and hopefully tell you more about the exception.
Once you figure out what the exception is, you should try to replace or augment it with something that does derive from std::exception. Having to catch (...) at all is not great.
If you use GCC or Clang you can also try __cxa_current_exception_type()->name() to get the name of the current exception type.
Yes there is, but how useful it is is open to debate:
#include <exception>
#include <iostream>
using namespace std;
int f() {
throw "message";
}
int main() {
try {
f();
}
catch ( ... ) {
try {
throw;
}
catch( const char * s ) {
cout << "caught " << s << endl;
}
}
}
And to actually to answer your question, IMHO you should always have a catch(...) at
the top level of your code, that terminates (or otherwise handles) when presented with an unexpected exception in your application, in a manner fully documented by your application's manual.
I believe you should catch (...), if you have a reasonable course of action at that point and want the application to keep running.
You don't have to crash in order to generate a crash report, mind you. There's API for generating a mini-dump and you can do it in your SEH handler.
here's an approach I used on one project. it involves rethrowing until an exception type is matched against a list of known exceptions and then dispatching some action upon a match (in this case just returning some string information, but it could also be calling a registered function object).
This idea can be extended into a dynamic registry of exception types if you wish, the thing you have to be careful of is to ensure that the list is in most-derived to least-derived order (requires a lot of rethrowing and catching during registration!)
#include <iostream>
#include <stdexcept>
#include <exception>
#include <typeinfo>
#include <system_error>
namespace detail {
// a function which compares the current exception against a list of exception types terminated
// with a void type
// if a match is made, return the exception (mangled) class name and the what() string.
// note that base classes will be caught if the actual class is not mentioned in the list
// and the list must be in the order of most-derived to least derived
//
template<class E, class...Rest>
std::string catcher_impl()
{
try
{
std::rethrow_exception(std::current_exception());
}
catch(const E& e)
{
bool is_exact = typeid(E) == typeid(e);
return std::string(typeid(E).name()) + (is_exact ? "(exact)" : "(base class)") + " : " + e.what();
}
catch(...)
{
return catcher_impl<Rest...>();
}
return "unknown";
}
// specialise for end of list condition
template<> std::string catcher_impl<void>()
{
return "unknown exception";
}
}
// catcher interface
template<class...Es>
std::string catcher()
{
return detail::catcher_impl<Es..., void>();
}
// throw some exception type
// and then attempt to identify it using the type list available
//
template<class E>
void test(E&& ex)
{
try
{
throw std::forward<E>(ex);
}
catch(...)
{
std::cout << "exception is: "
<< catcher<std::invalid_argument, std::system_error, std::runtime_error, std::logic_error>()
<< std::endl;
}
}
int main()
{
test(std::runtime_error("hello world"));
test(std::logic_error("my logic error"));
test(std::system_error(std::make_error_code(std::errc::filename_too_long)));
test(std::invalid_argument("i don't like arguments"));
struct my_runtime_error : std::runtime_error
{
using std::runtime_error::runtime_error;
};
test(my_runtime_error("an unlisted error"));
}
example output:
exception is: St13runtime_error(exact) : hello world
exception is: St11logic_error(exact) : my logic error
exception is: NSt3__112system_errorE(exact) : File name too long
exception is: St16invalid_argument(exact) : i don't like arguments
exception is: St13runtime_error(base class) : an unlisted error