473,583 Members | 3,420 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

rethrowing exceptions: why does this happen?

I haven't thought about rethrowing an exception in a long time, and tried to
do it the wrong way. Now I'm curious about /why/ it's wrong. My
expectation was that the exception instance would simply be passed up the
call stack as the same object. It would therefore behave polymorphically .
Is the behavior shown below compiler-specific? I'm using gcc 4.0.2.

In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?

#include <stdexcept>
#include <iostream>
void generate(){
throw std::invalid_ar gument("generat e() invalid argument exception");
}

void handle(bool broken) {
try {
generate();
} catch (std::exception & e) {
std::cout<< "handle:"<< e.what() <<std::endl;
if(broken)throw e;
throw;
}
}

void rehandle(bool broken=false) {
try {
handle(broken);
} catch (std::exception & e) {
std::cout<< "rehandle:" << e.what() <<std::endl;
if(broken)throw e;
throw;
}
}
int main() {
try {
rehandle();
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}

try {
rehandle(true);
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}
}

/*-----------output---------
handle:generate () invalid argument exception
rehandle:genera te() invalid argument exception
main:generate() invalid argument exception
handle:generate () invalid argument exception
rehandle:St9exc eption
main:St9excepti on
*/
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Nov 17 '06 #1
5 2851
Steven T. Hatton wrote:
>
In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?
A throw-expression throws creates a temporary object whose type is the
static type of its argument. Since e is a reference to std::exception,
the type of the temporary object is std::exception.

Forget for the moment that e is a reference to the exception object.
Pretend that it's just some reference to an object of type
std::exception. In that case, the only legitimate copy you could make of
it would be an object of type std::exception, because you don't know
it's dynamic type.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Nov 17 '06 #2
Steven T. Hatton wrote:
I haven't thought about rethrowing an exception in a long time, and tried to
do it the wrong way. Now I'm curious about /why/ it's wrong. My
expectation was that the exception instance would simply be passed up the
call stack as the same object. It would therefore behave polymorphically .
Is the behavior shown below compiler-specific? I'm using gcc 4.0.2.

In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?
Becuase "throw e" makes a copy of e and since the type is
"std::exception ", you get a slice of the "invalid_argume nt" exception
and loose any information about the exception. "throw" however throws
the same object that was caught.
Nov 17 '06 #3

Steven T. Hatton wrote:
I haven't thought about rethrowing an exception in a long time, and tried to
do it the wrong way. Now I'm curious about /why/ it's wrong. My
expectation was that the exception instance would simply be passed up the
call stack as the same object. It would therefore behave polymorphically .
Is the behavior shown below compiler-specific? I'm using gcc 4.0.2.

In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?

#include <stdexcept>
#include <iostream>
void generate(){
throw std::invalid_ar gument("generat e() invalid argument exception");
}

void handle(bool broken) {
try {
generate();
} catch (std::exception & e) {
std::cout<< "handle:"<< e.what() <<std::endl;
if(broken)throw e;
throw;
}
}

void rehandle(bool broken=false) {
try {
handle(broken);
} catch (std::exception & e) {
std::cout<< "rehandle:" << e.what() <<std::endl;
if(broken)throw e;
throw;
}
}
int main() {
try {
rehandle();
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}

try {
rehandle(true);
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}
}

/*-----------output---------
handle:generate () invalid argument exception
rehandle:genera te() invalid argument exception
main:generate() invalid argument exception
handle:generate () invalid argument exception
rehandle:St9exc eption
main:St9excepti on
*/
--
You are rethrowing a copied slice of the original object.

#include <iostream>
#include <typeinfo>

struct Base
{
virtual ~Base() { }
};

struct Derived : public Base
{
};

void foo()
{
try {
throw Derived();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
// throw;
throw r_b; // copy a slice
}
}

int main()
{
try {
foo();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
}
}

/*
Derived
Base
*/

Nov 17 '06 #4
Salt_Peter wrote:
>
Steven T. Hatton wrote:
>I haven't thought about rethrowing an exception in a long time, and tried
to
do it the wrong way. Now I'm curious about /why/ it's wrong. My
expectation was that the exception instance would simply be passed up the
call stack as the same object. It would therefore behave
polymorphicall y.
Is the behavior shown below compiler-specific? I'm using gcc 4.0.2.

In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?

#include <stdexcept>
#include <iostream>
void generate(){
throw std::invalid_ar gument("generat e() invalid argument exception");
}

void handle(bool broken) {
try {
generate();
} catch (std::exception & e) {
std::cout<< "handle:"<< e.what() <<std::endl;
if(broken)throw e;
throw;
}
}

void rehandle(bool broken=false) {
try {
handle(broken);
} catch (std::exception & e) {
std::cout<< "rehandle:" << e.what() <<std::endl;
if(broken)throw e;
throw;
}
}
int main() {
try {
rehandle();
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}

try {
rehandle(true);
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}
}

/*-----------output---------
handle:generat e() invalid argument exception
rehandle:gener ate() invalid argument exception
main:generate( ) invalid argument exception
handle:generat e() invalid argument exception
rehandle:St9ex ception
main:St9except ion
*/
--

You are rethrowing a copied slice of the original object.

#include <iostream>
#include <typeinfo>

struct Base
{
virtual ~Base() { }
};

struct Derived : public Base
{
};

void foo()
{
try {
throw Derived();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
// throw;
throw r_b; // copy a slice
}
}

int main()
{
try {
foo();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
}
}

/*
Derived
Base
*/
I believe Pete Becker had it right. Even if I pass the same time as the
original event, it comes out empty. What happens is that the compiler
borrows the constructor from the class used as the catch parameter, and
constructs a new instance.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Nov 20 '06 #5

Steven T. Hatton wrote:
Salt_Peter wrote:

Steven T. Hatton wrote:
I haven't thought about rethrowing an exception in a long time, and tried
to
do it the wrong way. Now I'm curious about /why/ it's wrong. My
expectation was that the exception instance would simply be passed up the
call stack as the same object. It would therefore behave
polymorphically .
Is the behavior shown below compiler-specific? I'm using gcc 4.0.2.
re>
In terms of what goes on at runtime, why does the `throw e' act as if I
threw a raw std::exception?

#include <stdexcept>
#include <iostream>
void generate(){
throw std::invalid_ar gument("generat e() invalid argument exception");
}

void handle(bool broken) {
try {
generate();
} catch (std::exception & e) {
std::cout<< "handle:"<< e.what() <<std::endl;
if(broken)throw e;
throw;
}
}

void rehandle(bool broken=false) {
try {
handle(broken);
} catch (std::exception & e) {
std::cout<< "rehandle:" << e.what() <<std::endl;
if(broken)throw e;
throw;
}
}
int main() {
try {
rehandle();
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}

try {
rehandle(true);
} catch(std::exce ption& e) {
std::cout<< "main:"<< e.what() <<std::endl;
}
}

/*-----------output---------
handle:generate () invalid argument exception
rehandle:genera te() invalid argument exception
main:generate() invalid argument exception
handle:generate () invalid argument exception
rehandle:St9exc eption
main:St9excepti on
*/
--
You are rethrowing a copied slice of the original object.

#include <iostream>
#include <typeinfo>

struct Base
{
virtual ~Base() { }
};

struct Derived : public Base
{
};

void foo()
{
try {
throw Derived();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
// throw;
throw r_b; // copy a slice
}
}

int main()
{
try {
foo();
}
catch(const Base& r_b)
{
std::cerr << typeid(r_b).nam e();
std::cerr << std::endl;
}
}

/*
Derived
Base
*/

I believe Pete Becker had it right. Even if I pass the same time as the
original event, it comes out empty. What happens is that the compiler
borrows the constructor from the class used as the catch parameter, and
constructs a new instance.
In the case where you throw a base or attempt reconstruction of the
derived object, yes.
In the case you *rethrow* the derived exception, however, the catch
block in main captures the original derived object via a pointer to its
base.
output:
/*
Derived
Derived
*/
To "pass" or rethrow the original "event":
throw; // rethrow the exception

--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Nov 20 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

33
2981
by: Steven Bethard | last post by:
I feel like this has probably been answered before, but I couldn't find something quite like it in the archives. Feel free to point me somewhere if you know where this has already been answered. I have a list in a particular order that I want to split into two lists: the list of every nth item, and the list of remaining items. It's...
26
2880
by: OvErboRed | last post by:
I just read a whole bunch of threads on microsoft.public.dotnet.* regarding checked exceptions (the longest-running of which seems to be <cJQQ9.4419 $j94.834878@news02.tsnz.net>. My personal belief is that checked exceptions should be required in .NET. I find that many others share the same views as I do. It is extremely frustrating to have...
2
1714
by: Martin Smith | last post by:
If a class has no need for any specific clean up code in a particular catch block is there any benefit to catching and rethrowing exceptions, rather than just letting the original exception bubble up to the calling function If so what?
822
29251
by: Turamnvia Suouriviaskimatta | last post by:
I 'm following various posting in "comp.lang.ada, comp.lang.c++ , comp.realtime, comp.software-eng" groups regarding selection of a programming language of C, C++ or Ada for safety critical real-time applications. The majority of expert/people recommend Ada for safety critical real-time applications. I've many years of experience in C/C++...
2
4371
by: Lasse Vågsæther Karlsen | last post by:
If I got the following code: try { // something that might throw an exception } catch (Exception ex) { // Log contents of ex here throw;
4
1843
by: Steve | last post by:
I have read a couple articles online, read my Jesse Liberty book but I am still confused as to just what the best practices are for using exceptions. I keep changing how I'm working with them and it has now, after 15k lines of code resulted in a royal mess! It's my hope to ask some specific questions with scenario examples and that some of...
15
1881
by: =?Utf-8?B?TWljaGVsIFBvc3NldGggW01DUF0=?= | last post by:
In my opinion rethrowing exceptions without providing anny extra information is a totall waste Examples : in my opinion wrong : A: Public sub DoSomeStuff() Try do it
4
2367
by: Coder Guy | last post by:
I am implementing an asynchronous handler (similar to Control.EndInvoke) and if the other thread throws an exception, I catch it and rethrow it on the current thread. How can I rethrow the exception on the current thread while maintaining the stack trace? The best I've come up with is encapsulating the exception as an inner exception. I...
13
1876
by: valentin tihomirov | last post by:
I do not understand something. A caught exception stack points to an argument-free 'throw' in a catch block. Meantime, it is widely known that these statements re-throw the original exceptions. I expected, therefore, that the stack points to the original 'throw e' code line.
0
7824
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8321
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7931
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
8191
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5370
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3816
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3841
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2331
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
0
1154
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.