473,416 Members | 1,548 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,416 software developers and data experts.

exception catch

Hi Everyone,

I have the following exception class,

class E1
{
};

class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};

int main()
{
try
{
throw E1();
}
catch(E2 obj)
{
printf("first handler\n");
}
catch(E1 obj1)
{
printf("second handler\n");
}
}

IN the above case, the E1 object is not converted into E2 and is
handled by the second handler, this suggests that automatic type
conversion doesn't happen with exceptions, i was wondering if this is
specified in standards and is there any reason for that?

Thanks in advance!!!
Dec 8 '07 #1
10 2011
Rahul wrote:
Hi Everyone,

I have the following exception class,

class E1
{
};

class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};

int main()
{
try
{
throw E1();
}
catch(E2 obj)
Don't catch exceptions by value, use a const reference.

--
Ian Collins.
Dec 8 '07 #2
Rahul wrote:
Hi Everyone,

I have the following exception class,

class E1
{
};

class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};

int main()
{
try
{
throw E1();
}
catch(E2 obj)
{
printf("first handler\n");
}
catch(E1 obj1)
{
printf("second handler\n");
}
}

IN the above case, the E1 object is not converted into E2 and is
handled by the second handler, this suggests that automatic type
conversion doesn't happen with exceptions, i was wondering if this is
specified in standards and is there any reason for that?
It is specified in [15.3/3].

As for a reason, I can only guess. However, I would conjecture that the
problem is that when you throw, you do not necessarily have control over
the catch. I.e., a library component might throw precisely because it
cannot handle the condition locally and wants the client code to supply a
catch handler. If you allowed for user-defined conversions in this setting,
there could be surprise catch-matches.
Best

Kai-Uwe Bux
Dec 8 '07 #3
In article
<9a**********************************@i29g2000prf. googlegroups.com>,
Rahul <sa*****@yahoo.co.inwrote:
Hi Everyone,

I have the following exception class,

class E1
{
};

class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};

int main()
{
try
{
throw E1();
}
catch(E2 obj)
{
printf("first handler\n");
}
catch(E1 obj1)
{
printf("second handler\n");
}
}

IN the above case, the E1 object is not converted into E2 and is
handled by the second handler, this suggests that automatic type
conversion doesn't happen with exceptions, i was wondering if this is
specified in standards and is there any reason for that?
That is correct, according to 15.3. In my opinion, this is a desired
behavior, as exception handlers are meant to handle specific exceptions,
not simply any exception that can be conveniently converted. Imagine the
confusion when you have a more-appropriate exception handler higher up
the call tree, and some other exception handler down below preempts it
due to automatic type conversion.

Note that exception handlers will handle an exception if it is a derived
class of its parameter type.

-dr
Dec 9 '07 #4
On Dec 8, 4:04 pm, Ian Collins <ian-n...@hotmail.comwrote:
Rahul wrote:
Hi Everyone,
I have the following exception class,
class E1
{
};
class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};
int main()
{
try
{
throw E1();
}
catch(E2 obj)

Don't catch exceptions by value, use a const reference.

--
Ian Collins.
Why do you say that exception's should be caught by value?
is it because of object slicing when a derived class exception is
caught by a base class exception handler?
Dec 9 '07 #5
On Dec 9, 10:34 am, "Alf P. Steinbach" <al...@start.nowrote:
* Rahul:


On Dec 8, 4:04 pm, Ian Collins <ian-n...@hotmail.comwrote:
Rahul wrote:
Hi Everyone,
I have the following exception class,
class E1
{
};
class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};
int main()
{
try
{
throw E1();
}
catch(E2 obj)
Don't catch exceptions by value, use a const reference.
--
Ian Collins.
Why do you say that exception's should be caught by value?
is it because of object slicing when a derived class exception is
caught by a base class exception handler?

On reason is to avoid copy construction.

Consider the case where the copy constructor might trow (e.g. allocating
a string).

A copy construction exception at the throw point is bad but at least you
do get an exception -- just not necessarily the one you asked for --
but a copy construction exception at catch point is t r o u b l e.
Aren't exceptions thrown always copied (atleast once) after they are
thrown and before they are caught? To make it persistent during the
stack unwinding? And if copy construction can throw, it is a problem
even before catching the exception. I think the most important reason
for not catching exceptions by value is efficiency i.e. we avoid
atleast one copy creation of the exception object.

The other reason could be writing a generic base exception handler
where all derived types can be caught without slicing.
Dec 9 '07 #6
On Dec 9, 11:27 am, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 9, 10:34 am, "Alf P. Steinbach" <al...@start.nowrote:
* Rahul:
On Dec 8, 4:04 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Rahul wrote:
>>Hi Everyone,
>> I have the following exception class,
>>class E1
>>{
>>};
>>class E2
>>{
>>public: E2(const E1&)
>> {
>> printf("automatic type conversion\n");
>> }
>>};
>>int main()
>>{
>> try
>> {
>> throw E1();
>> }
>> catch(E2 obj)
>Don't catch exceptions by value, use a const reference.
>--
>Ian Collins.
Why do you say that exception's should be caught by value?
is it because of object slicing when a derived class exception is
caught by a base class exception handler?
On reason is to avoid copy construction.
Consider the case where the copy constructor might trow (e.g. allocating
a string).
A copy construction exception at the throw point is bad but at least you
do get an exception -- just not necessarily the one you asked for --
but a copy construction exception at catch point is t r o u b l e.

Aren't exceptions thrown always copied (atleast once) after they are
thrown and before they are caught? To make it persistent during the
stack unwinding? And if copy construction can throw, it is a problem
even before catching the exception. I think the most important reason
for not catching exceptions by value is efficiency i.e. we avoid
atleast one copy creation of the exception object.

The other reason could be writing a generic base exception handler
where all derived types can be caught without slicing.
Yes i think so, they are copied atleast once, and this code
illustrates the same,

class E
{
public : E()
{
printf("in default constructor...\n");
}
E(const E& ref)
{
printf("copy constructor is invoked...\n");
}
};

int main()
{
try
{
printf("in try\n");
throw E();
}
catch(E& ref)
{
printf("in handler\n");
}
return(0);
}

output is

in try
in default constructor...
copy constructor is invoked...
in handler
Press any key to continue
Dec 9 '07 #7
On 2007-12-09 00:56, Dave Rahardja wrote:
In article
<9a**********************************@i29g2000prf. googlegroups.com>,
Rahul <sa*****@yahoo.co.inwrote:
>Hi Everyone,

I have the following exception class,

class E1
{
};

class E2
{
public: E2(const E1&)
{
printf("automatic type conversion\n");
}
};

int main()
{
try
{
throw E1();
}
catch(E2 obj)
{
printf("first handler\n");
}
catch(E1 obj1)
{
printf("second handler\n");
}
}

IN the above case, the E1 object is not converted into E2 and is
handled by the second handler, this suggests that automatic type
conversion doesn't happen with exceptions, i was wondering if this is
specified in standards and is there any reason for that?

That is correct, according to 15.3. In my opinion, this is a desired
behavior, as exception handlers are meant to handle specific exceptions,
not simply any exception that can be conveniently converted. Imagine the
confusion when you have a more-appropriate exception handler higher up
the call tree, and some other exception handler down below preempts it
due to automatic type conversion.
That would never happen since the handlers are tried top down for a
match and the first match is used. So if an exact match is above one
that would require a conversion the exact match would always be used.

I believe that what you were thinking of was the reverse, when the
handler requiring a conversion was placed above the exact match, in
which case the match requiring a conversion would be used. Notice that
this can happen if you have a handler taking a base-class above a
handler for a derived class, the handler for the derived class would
never be used.

--
Erik Wikström
Dec 9 '07 #8
On Dec 9, 7:27 am, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
On Dec 9, 10:34 am, "Alf P. Steinbach" <al...@start.nowrote:
* Rahul:
On Dec 8, 4:04 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Rahul wrote:
>>Hi Everyone,
>> I have the following exception class,
>>class E1
>>{
>>};
>>class E2
>>{
>>public: E2(const E1&)
>> {
>> printf("automatic type conversion\n");
>> }
>>};
>>int main()
>>{
>> try
>> {
>> throw E1();
>> }
>> catch(E2 obj)
Concerning the original question: basically, the only
conversions considered are derived to base, and then only if the
base is an unambiguous public base. (In the case of pointers,
the conversion to void* is also considered---but you shouldn't
be throwing pointers---and in all cases, top level cv qualifiers
are ignored. And I think a few very, very basic conversions
also take place systematically: array to pointer, for example.)
>Don't catch exceptions by value, use a const reference.
Why do you say that exception's should be caught by value?
is it because of object slicing when a derived class exception is
caught by a base class exception handler?
On reason is to avoid copy construction.
Consider the case where the copy constructor might trow (e.g. allocating
a string).
A copy construction exception at the throw point is bad but at least you
do get an exception -- just not necessarily the one you asked for --
but a copy construction exception at catch point is t r o u b l e.
Aren't exceptions thrown always copied (atleast once) after they are
thrown and before they are caught? To make it persistent during the
stack unwinding? And if copy construction can throw, it is a problem
even before catching the exception.
The formal semantics of a throw is copy initialization of the
exception somewhere where it won't disappear. As always with
copy initialization, there must be an accessible copy
constructor, and as always, the compiler is allowed to elide the
copy constructor.

The exception is not considered as being thrown until this copy
is finished, however. If the copy triggers an exception, that
exception will be thrown, rather than the original exception.
The exception is not considered caught until the code in the
catch block is entered, after the copy (if the catch is by
value). And exception in this copy will cause terminate to be
called.
I think the most important reason
for not catching exceptions by value is efficiency i.e. we avoid
atleast one copy creation of the exception object.
Given all the rest that happes when you throw an exception, this
is not normally an issue.
The other reason could be writing a generic base exception handler
where all derived types can be caught without slicing.
That's probably the original motivation behind the rule to catch
by reference. As Alf pointed out, however, catch by reference
has become the "normal" way of doing things in C++; anytime you
do something else, the reader will wonder why. So even if
you're throwing a non-polymorphic object, you should still catch
by reference.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 10 '07 #9
On Dec 9, 9:20 am, Rahul <sam_...@yahoo.co.inwrote:
On Dec 9, 11:27 am, Abhishek Padmanabh
<abhishek.padman...@gmail.comwrote:
[...]
Yes I think so, they are copied atleast once, and this code
illustrates the same,
class E
{
public : E()
{
printf("in default constructor...\n");
}
E(const E& ref)
{
printf("copy constructor is invoked...\n");
}
};
int main()
{
try
{
printf("in try\n");
throw E();
}
catch(E& ref)
{
printf("in handler\n");
}
return(0);
}
output is
in try
in default constructor...
copy constructor is invoked...
in handler
Press any key to continue
This depends on the compiler. The compiler is allowed to elide
the copy, and all of the compilers I have access to (g++, Sun CC
and VC++) do (and don't output the line "copy constructor is
invoked..."). (This depends on the version, however---older
versions of g++ did call the copy constructor here.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 10 '07 #10
On Dec 8, 12:42 pm, Kai-Uwe Bux <jkherci...@gmx.netwrote:
Rahul wrote:
[...]
IN the above case, the E1 object is not converted into E2 and is
handled by the second handler, this suggests that automatic type
conversion doesn't happen with exceptions, i was wondering if this is
specified in standards and is there any reason for that?
It is specified in [15.3/3].
As for a reason, I can only guess. However, I would conjecture that the
problem is that when you throw, you do not necessarily have control over
the catch. I.e., a library component might throw precisely because it
cannot handle the condition locally and wants the client code to supply a
catch handler. If you allowed for user-defined conversions in this setting,
there could be surprise catch-matches.
Implementation considerations may also have played a role.
Remember that the type matching here takes place at runtime (and
so must use some form of RTTI). Derived to base is pretty
straight foreward to do dynamically, but anything else would
require a lot more information in the RTTI structures, and a lot
more work to process it. (Off hand, except for Derived to Base,
the only other conversion which needs to be considered
dynamically is pointer to void*.)

Note that some conversions occur at the throw site,
systematically, and thus do not require RTTI to support them.
Array to pointer, for example: you can declare a catch with a
reference to an array:
catch ( int const (&array)[ 5 ] )
for example, but there's nothing you can throw that will match
it, because the array will be converted to a pointer at the
throw site, before matching starts.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Dec 10 '07 #11

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

Similar topics

10
by: Gary.Hu | last post by:
I was trying to catch the Arithmetic exception, unsuccessfully. try{ int a = 0, b = 9; b = b / a; }catch(...){ cout << "arithmetic exception was catched!" << endl; } After ran the program,...
5
by: Kevin Jackson | last post by:
In the following code snippet, will the finally block be executed when the throw is executed in the catch block???? I'm assuming it will. catch (Exception e) { // if...
44
by: craig | last post by:
I am wondering if there are some best practices for determining a strategy for using try/catch blocks within an application. My current thoughts are: 1. The code the initiates any high-level...
40
by: Kevin Yu | last post by:
is it a bad programming design to throw exception in the try block then catch it??
3
by: will | last post by:
Hi all. I've got an question about how to catch an exception. In Page_Load, I place a DataGrid, dg1, into edit mode. This will call the method called GenericGridEvent. GenericGridEvent will call...
2
by: | last post by:
I would appreciate some help in understanding the simple C# example relating to handling exceptions. This one relates to catching an error thrown by dividing number by zero. There are a few...
6
by: Vadivel Kumar | last post by:
I've a problem in handling a custom exception The following is my custom exception class: public class AppException : public Exception { public AppException (string message, Exception...
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...
11
by: l.woods | last post by:
I want to set up my CATCH for a specific exception, but I really don't know which one of the multitude that it is. I am getting the exception now with Catch ex as Exception but I want to be...
7
by: Sek | last post by:
Hi Folks! I was pondering over a code and noticed that exception handlers were present in the private, protected as well as public methods. And, ofcourse, public methods were calling priv/prot...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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:
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
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...
0
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
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...

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.