473,385 Members | 2,274 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

What to throw?

Ken
Hi. I know it is recommended that exceptions should be caught by
reference, but are there recommendations for how an exception should
be thrown? Or is it just a matter of throwing a type that is
compatiple with the catch. If that is the case, I suppose that if you
are catching a reference to exception e, the exception being thrown
better be an instance of e or a reference to an instance of e (ie., if
you threw a pointer to e and caught a reference to e, the compiler
would generate an error).

Thanks for any clarification and/or correction,

Ken
Jul 22 '05 #1
5 1838
Ken wrote:
Hi. I know it is recommended that exceptions should be caught by
reference, but are there recommendations for how an exception should
be thrown? Or is it just a matter of throwing a type that is
compatiple with the catch. If that is the case, I suppose that if you
are catching a reference to exception e, the exception being thrown
better be an instance of e or a reference to an instance of e (ie., if
you threw a pointer to e and caught a reference to e, the compiler
would generate an error).


You got the compatibility bit correctly. But just like in the rest
of the language, "compatible" (or, correctly, "convertible") is more
than just "the same". You can throw a object of a class derived
from what you're going to catch by reference, for example.

Also, the compiler shouldn't generate an error if you throw a pointer
when trying to catch a reference. Somebody else might be expecting
that pointer. You will likely get "uncaught exception" during run-
time.

------------------------------------ example
struct A {};
struct B : A {};

void foo() { throw B(); }
void bar() {}

int main() {
try {
foo();
}
catch (A&) {
bar(); // you should end up here during execution
}
return 0;
}

------------------------------------ another example:
struct A {};
struct B : A {};

void foo() { throw new B(); }
void bar() {}

int main() {
try {
foo();
}
catch (A&) {
bar(); // maybe somebody will throw a reference...
}
catch (A*) {
bar(); // you should end up here because it's really a B*
}
return 0;
}
--------------------------------------

HTH

Victor
Jul 22 '05 #2
Ken
Victor Bazarov <v.********@comAcast.net> wrote in message news:<zq******************@dfw-read.news.verio.net>...
Thanks so much for the examples!

Just one follow-up: In the example below, let's say I replaced foo
with:

void foo()
{
B *myB;
myB = new B();
throw *myB;
}

Would this get caught by the reference catch (as opposed to the
pointer)? If so, does this mean that the copy made for the throw
would be a copy of the B instance as opposed to a copy of the pointer?
If so, I'm wondering if this is what I really need to do to avoid a
memory leak:

void foo()
{
B *myB;
myB = new B();
throw *myB;
delete myB;
}

On the otherhand, I'm thinking that the best way to do this is:

void foo()
{
B myB;
throw myB;
}

My assumption is that this, too, would get caught by the reference
catch statement. Is this correct?

Also, are there any advantages to throwing a pointer instead? Looking
at all this, it seems to me like a general rule of thumb would be to
just throw by value and catch by reference. Does this seem right?

Thanks again for any input!

Ken


------------------------------------ another example:
struct A {};
struct B : A {};

void foo() { throw new B(); }
void bar() {}

int main() {
try {
foo();
}
catch (A&) {
bar(); // maybe somebody will throw a reference...
}
catch (A*) {
bar(); // you should end up here because it's really a B*
}
return 0;
}
--------------------------------------

HTH

Victor

Jul 22 '05 #3
"Ken" <kk****@yahoo.com> wrote...
Victor Bazarov <v.********@comAcast.net> wrote in message news:<zq******************@dfw-read.news.verio.net>... Thanks so much for the examples!

Just one follow-up: In the example below, let's say I replaced foo
with:

void foo()
{
B *myB;
myB = new B();
throw *myB;
}

Would this get caught by the reference catch (as opposed to the
pointer)?
Of course! The type of *myB is l-value of B, and as such can be bound
to B&.
If so, does this mean that the copy made for the throw
would be a copy of the B instance as opposed to a copy of the pointer?
There is no copy made for the throw. Why would there be?
If so, I'm wondering if this is what I really need to do to avoid a
memory leak:

void foo()
{
B *myB;
myB = new B();
throw *myB;
delete myB;
This is unreachable code. You will need to do "delete (&<caught_ref>)"
whe you catch the object.
}

On the otherhand, I'm thinking that the best way to do this is:

void foo()
{
B myB;
throw myB;
Or, simply

throw B(); // no need to declare the local object
}

My assumption is that this, too, would get caught by the reference
catch statement. Is this correct?
I believe so.

Also, are there any advantages to throwing a pointer instead? Looking
at all this, it seems to me like a general rule of thumb would be to
just throw by value and catch by reference. Does this seem right?


Throwing a pointer does indeed seem unnecessary. However, if you
want to be simple you can always do

...
throw "such and such error";

...
catch (char const* errormsg) // catching a pointer
{
cerr << errormsg;
...
}

V
Jul 22 '05 #4
Ken
"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<r0Eyc.73993$3x.32729@attbi_s54>...
If so, does this mean that the copy made for the throw
would be a copy of the B instance as opposed to a copy of the pointer?


There is no copy made for the throw. Why would there be?


I believe that C++ creates a temporary copy of the exception object
being thrown.

See http://www.devx.com/tips/Tip/12707. This says that:

"...when an exception is thrown, the mechanism first searches for an
appropriate handler in the current scope. If such handler does not
exist, all local objects are destroyed, the exception object itself is
copied on the stack of the function that is higher in the calling
chain, and only then is the current scope exited."

So behind the scenes, it is a copy of the exception object that goes
the next level up.

- Ken
Jul 22 '05 #5
Ken wrote:

"Victor Bazarov" <v.********@comAcast.net> wrote in message news:<r0Eyc.73993$3x.32729@attbi_s54>...
If so, does this mean that the copy made for the throw
would be a copy of the B instance as opposed to a copy of the pointer?
There is no copy made for the throw. Why would there be?


I believe that C++ creates a temporary copy of the exception object
being thrown.


It may, but it doesn't have to. Temporaries may be optimised away by
the compiler, though you cannot make much use of that fact. In
particular, the object thrown must be still destructible and
copy-constructible; also, you cannot rely on the object that you catch
(even if by reference) being the same as the one thrown.

With every compiler I have, when catching by reference, no copies are
created. If I try catching by value rather than by reference, a
temporary for the catch statement is copy-constructed, but I believe
it too is allowed to be eliminated if it is const.

See http://www.devx.com/tips/Tip/12707. This says that:

"...when an exception is thrown, the mechanism first searches for an
appropriate handler in the current scope. If such handler does not
exist, all local objects are destroyed, the exception object itself is
copied on the stack of the function that is higher in the calling
chain, and only then is the current scope exited."


The stack is only guaranteed to be unwound if an appropriate handler
is found in some enclosing scope. If not, it may or may not be
unwound (and, accordingly, local objects may or may not be destructed)
before terminate() is called.
Denis
Jul 22 '05 #6

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

Similar topics

24
by: Steven T. Hatton | last post by:
If I understand correctly, I have no assurance that I can determine the type of a simple class instance thrown as an exception unless I explicitly catch it by name. (non-derived classes having no...
10
by: linq936 | last post by:
Hi, I have many assert() call in my code, now I am considering to replace them with exception. The reason I want to do this change is that with the program going bigger and bigger, it is hard to...
13
by: Jason Huang | last post by:
Hi, Would someone explain the following coding more detail for me? What's the ( ) for? CurrentText = (TextBox)e.Item.Cells.Controls; Thanks. Jason
4
by: Rob Richardson | last post by:
Greetings! I am working on an application that targets a Pocket PC running Windows CE and SQL Server CE. Almost all functions in the application use a Try block with a Catch block that looks...
37
by: Egbert Nierop \(MVP for IIS\) | last post by:
In win32 mode, a BSTR was UINT length prefixed and terminated exactly by a zero char. So if you allocated "Hello World" that would allocate 28 bytes. In x64 and (IA64 as well) it would become...
12
by: EvilOldGit | last post by:
In Stroustrup he talks of a MathErr class that you can use to catch floating point exceptions. It doesn't exist, at least not in Visual C++ I can catch FP exceptions using catch(...) but am...
2
by: Zytan | last post by:
I know that WebRequest.GetResponse can throw WebException from internet tutorials. However in the MSDN docs: http://msdn2.microsoft.com/en-us/library/system.net.webrequest.getresponse.aspx It...
28
by: gnuist006 | last post by:
I have some code like this: (if (test) (exit) (do something)) or (if (test)
167
by: darren | last post by:
Hi I have to write a multi-threaded program. I decided to take an OO approach to it. I had the idea to wrap up all of the thread functions in a mix-in class called Threadable. Then when an...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
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...

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.