Jump to content

Talk:C++ Programming/Exception Handling

Page contents not supported in other languages.
Add topic
From Wikibooks, open books for an open world
Latest comment: 14 years ago by Danilo.Piazzalunga in topic Throwing objects: catch by value

Throw Declarations

[edit source]

A nice future enhancement to this section would be to discuss throw declarations in function signatures: what they mean, how to use them, and disadvantages of using them. Jlenthe (talk) 13:26, 14 June 2009 (UTC)Reply

Unhandled exceptions

[edit source]

"Unhandled exceptions on the other hand will result in a function termination and the stack will be unwound (allocated objects will have destructors called) [...]"

This is not true (at least for g++).

#include <iostream> class Test { public:	Test() { std::cerr << "ctor called" << std::endl; std::cerr.flush(); }	~Test() { std::cerr << "dtor called" << std::endl; std::cerr.flush(); }	void aaargh() { throw "aaargh!"; } }; int main(int argc, char **argv) {	Test t;	t.aaargh();	return 0; } 

results in following output:

$ g++ test.c $ ./a.out ctor called terminate called after throwing an instance of 'char const*' Aborted $ g++ --version g++ (Debian 4.3.2-1.1) 4.3.2 

Obviously the destructor is not called. It seems as if the elements on the stack only get cleanly deallocated iff there is a try-catch-block:

int main(int argc, char **argv) {	try	{	Test t;	t.aaargh();	}	catch(...)	{	throw;	}	return 0; } 

results in following output:

$ g++ test.c $ ./a.out ctor called dtor called terminate called after throwing an instance of 'char const*' Aborted 
The ISO rules are a bit more complicated than what is written here. If an exception goes completely uncaught even in the main() function, the program is terminated. Whether the stack is unwound and destructors called before termination in that situation is implementation defined. The results you see is within the ISO rules. Unwinding of t happens and the destructor called in the second example because the uncaught exception in the aaargh() function is caught in the main() function. Also t is constructed within the try block and before the try block jumps to the catch t is destroyed if I've understood the ISO standard correctly. You might get different results if you print a message before throw in the catch handler depending on whether t is constructed before or in the try block as well:
int main() { Test t; try { t.aaargh(); } catch(...) { std:cerr << "caught exception" << std::endl; std::cerr.flush(); } }
int main() { try { Test t; t.aaargh(); } catch(...) { std:cerr << "caught exception" << std::endl; std::cerr.flush(); } }
--darklama 14:34, 1 September 2010 (UTC)Reply

empty throw

[edit source]

There was a comment in the original text which says "An empty throw can only exist in a catch block" This is Not true . You can also put empty throw in try block. But be careful ! For example this empty throw is not catch-able hence useless

int main() { try{ throw ; }catch(...){ cout << "What do you think you are doing ?? " ; } return 0 ; }
bash>> g++ exceptionClasses.cpp bash>> ./a.out terminate called without an active exception Abort

One usage would be to re-use empty throw based function to catch some other function's exception and forward e.g. extending above example


void mymain(){ try{ throw ; }catch(...){ cout << " What do you think you are doing ?? " ; } } int main(){ try { throw "May be this makes sense !" ; }catch(const char * str){ cout << str << endl  ; mymain() ; } return 0 ; } 
bash>>./a.out May be this makes sense ! What do you think you are doing ??

—The preceding unsigned comment was added by Manish baphna (talkcontribs) .

You are partially correct. The standard does not forbid an empty throw from being placed anywhere. According to the standard an empty throw has the effect of throwing the most recently caught exception that hasn't finished being processed. I believe this is seen in your second example. In the mymain() function I believe the throw results in "May be this makes sense !" being rethrown and caught because that was in the middle of a catch that hadn't finished being processed. However the standard also says the program is to be terminated if there is no active exception currently being caught, which is what is seen in the first example. The only reason the throw isn't caught is because the program is terminated due to there being no active exceptions. This could be interpreted to mean that an empty throw can exist outside of any try-catch block too, but doing so results in program termination, just as the first example did: int main() { throw; return 0; }. --darklama 12:08, 22 October 2010 (UTC)Reply

Java references

[edit source]

C++ is not Java. It shouldn't be compared to Java. There are nearly countless OOP languages out there (vm'd and natively compiled) that C++ could be compared to, but it's not. Let's not start. That's a slippery slope of, "Oh, let's teach [Insert language here] developers how to program in C++ by comparison." I went ahead and removed references. Prime (discusscontribs)

We have a section for that sort of comparisons that will always crop up. Can you check out Java section of the book and see if what you removed here is correctly demonstrated there ? Thanks. --Panic (discusscontribs) 04:06, 5 June 2011 (UTC)Reply

Throwing objects: catch by value

[edit source]

"But now, the catch handler that catches the exception, does it by value, meaning that a copy constructor is called. This can cause the program to crash if the exception caught was a bad_alloc caused by insufficient memory."

Are you sure about this? Catching the exception by value means that the copy is created on the stack, not on the heap. IIRC, only new can throw bad_alloc. Danilo.Piazzalunga (discusscontribs) 19:18, 14 July 2011 (UTC)Reply