473,385 Members | 1,867 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.

why are thrown objects copied twice?

Hi,

I would like to know why objects that are thrown to be caught are
copy-constructed more than once.

I have seen this behaviour after running the following simple program
that is an exercise (adapted from F.Brokken C++ Annotations) only to
see constructors at work:

/* exception.cpp */

#include <iostream>
#include <string>

using namespace std;

class Object
{
string name;
public:
Object(string n)
:name(n)
{
cout << "Object constructor of " << name << "\n";
}
Object(Object const &other)
:name(other.name + " (copy)")
{
cout << "Copy constructor for " << name << "\n";
}
~Object()
{
cout << "Object destructor of " << name << "\n";
}
friend void fun_1(Object obj)
{}
void fun_2()
{
Object Thrown("local object");
throw Thrown;
}
char const *get()
{
return name.c_str();
}
};

int main()
{
Object out("main object");

fun_1(out);

try
{
out.fun_2();
}
catch(Object obj)
{
cout << "Caught exception from " << obj.get() << "\n";
}
}

This is the output:

[myself@localhost /temporary]# ./exception
Object constructor of main object
Copy constructor for main object (copy)
Object destructor of main object (copy)
Object constructor of local object
Copy constructor for local object (copy)
Object destructor of local object
Copy constructor for local object (copy) (copy)
Caught exception from local object (copy) (copy)
Object destructor of local object (copy) (copy)
Object destructor of local object (copy)
Object destructor of main object

As you can see the copy constructor adds "(copy)" to the name of the
newly created object. I also put the call to fun_1() just to persuade
myself that an object that is passed by value is copied only once.

May be I am missing something obvious.

Thank you all in advance,

Fabio De Francesco.
Jul 22 '05 #1
9 1563
fm**@tiscali.it (fabio de francesco) wrote in
news:ba**************************@posting.google.c om:
Hi,

I would like to know why objects that are thrown to be caught are
copy-constructed more than once.


You are catching by value instead of by reference. This will result in a
copy being made of the thrown object, just as it would if you passed it
to a function by value.

Instead of

catch (Object obj)

try

catch (const Object& obj)

The first copy is made when you are throwing the non-temporary local
object.

Gregg
Jul 22 '05 #2
Fabio De Francesco wrote:
I would like to know why objects that are thrown to be caught are
copy-constructed more than once.
Gregg replied:
You are catching by value instead of by reference. This will result in a
copy being made of the thrown object, just as it would if you passed it
to a function by value.

Instead of

catch (Object obj)

try

catch (const Object& obj)


Doesn't work in Fabio's case, because he wants to call a non-const
member function of "obj" inside the catch clause. So instead, what
about using a non-const reference? As follows:

catch (Object& obj)
Regards,

Niels Dekker
www.xs4all.nl/~nd/dekkerware
Jul 22 '05 #3

"Niels Dekker - no reply address" <un*****@this.is.invalid> wrote in message
news:41**************@this.is.invalid...
Fabio De Francesco wrote:
I would like to know why objects that are thrown to be caught are
copy-constructed more than once.


Gregg replied:

You are catching by value instead of by reference. This will result in a
copy being made of the thrown object, just as it would if you passed it
to a function by value.

Instead of

catch (Object obj)

try

catch (const Object& obj)


Doesn't work in Fabio's case, because he wants to call a non-const
member function of "obj" inside the catch clause. So instead, what
about using a non-const reference? As follows:

catch (Object& obj)


It's OK, but better would be to declare get as const, like it should've been
in the first place.

char const *get() const
{
return name.c_str();
}

john
Jul 22 '05 #4
Gregg wrote:
You are catching by value instead of by reference. This will result in a
copy being made of the thrown object, just as it would if you passed it
to a function by value.

Instead of
catch (Object obj)
try
catch (const Object& obj)
I wrote: Doesn't work in Fabio's case, because he wants to call a non-const
member function of "obj" inside the catch clause. So instead, what
about using a non-const reference? As follows:

catch (Object& obj)
John Harrison replied:
It's OK, but better would be to declare get as const, like it should've been
in the first place.

char const *get() const
{
return name.c_str();
}

You're right, Object::get() should definitely be a const member
function. But still I find catching by non-const reference kinda
interesting... being allowed to modify that temporary exception object!
It still appears to catch const objects as well:

try
{
const Object ConstObj("const object");
throw ConstObj;
}
catch (Object& obj) // non-const reference
{
cout << "Caught exception from " << obj.get() << "\n";
}

Of course, it only catches a non-const copy of the "const object"...
Regards,

Niels Dekker
www.xs4all.nl/~nd/dekkerware
Jul 22 '05 #5
Niels Dekker - no reply address wrote:
Of course, it only catches a non-const copy of the "const object"...


Could someone cite /Effective C++/ by my tonsorial idol, Scott Meyers, here?
I think he covers a rationale for 'const'.

I'm to lazy to get my copy out of the closet...

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces
Jul 22 '05 #6
Phlip wrote:

Could someone cite /Effective C++/ by my tonsorial idol, Scott Meyers,
here? I think he covers a rationale for 'const'.


Do you mean "Item 21: Use const whenever possible"? It doesn't say
anything specific about catching exceptions as "const".

Or do you mean "Item 13: Catch exceptions by reference", from /More
Effective C++/? To my surprise, it suggests catching exceptions by
non-const reference!

More Effective C++, Item 13 says:

try {
someFunction(); // no change here
}
catch (exception& ex) { // here we catch by reference
// instead of by value
cerr << ex.what(); // now calls
// Validation_error::what(),
... // not exception::what()
}

(Cited from the Effective C++ CD, third pressing, June 1999.)
BTW, I'm a big fan of Scott Meyers as well, don't get me wrong! :-)
Niels Dekker
www.xs4all.nl/~nd/dekkerware
Jul 22 '05 #7
Gregg <gr***@invalid.invalid> wrote in message news:<Xn*********************************@207.69.1 89.194>...
fm**@tiscali.it (fabio de francesco) wrote in
news:ba**************************@posting.google.c om:
Hi,

I would like to know why objects that are thrown to be caught are
copy-constructed more than once.
You are catching by value instead of by reference. This will result in a
copy being made of the thrown object, just as it would if you passed it
to a function by value.


If it is "...just as it would if you passed it to a function by
value." why passing an object to a function by value makes only a
single copy, whereas we have two copies with "throw-catch"?
Instead of

catch (Object obj)

try

catch (const Object& obj)
I already know. This is not the point.
The first copy is made when you are throwing the non-temporary local
object.
And the second one?
Gregg


OK, I am sure that because of my poor English I wasn't able to explain
what is the question I would like to have an answer for.

I hate to repeat myself but may be this time I will be able to better
explain the issue.

I know that I'm passing by value instead of by reference. I already
know how to avoid unneeded copies (more than one copy in this case)
with const object reference or similar.

What interests me is to understand why the throw-catch mechanism needs
to copy the object twice, whereas the similar simple passing of an
object by value does a unique single copy of the original.

I have put a call to the function "void fun_1(Object obj)" with the
intention to show a contrast to the other case when I have two copies
(passing by value too).

Please look carefully at lines #6 and #8 of the program output:

1) [myself@myhost /temporary]# ./exception
2) Object constructor of main object
3) Copy constructor for main object (copy)
4) Object destructor of main object (copy)
5) Object constructor of local object
6) Copy constructor for local object (copy)
7) Object destructor of local object
8) Copy constructor for local object (copy) (copy)
9) Caught exception from local object (copy) (copy)
10) Object destructor of local object (copy) (copy)
11) Object destructor of local object (copy)
12) Object destructor of main object

What I see is a first copy-construction of the local object (#6) in
fun_2() then the destruction of the local object (#7), that is OK, and
eventually a second copy-construction of the same local object. These
objects are destroyed at lines #10 and #11.
This behaviour constrasts to what we see at #3 where only a single
copy-construction is made when passing an object by value to fun_1().

Thank you all. I am sorry for all the repetitions of the same concepts
I had to make.

Ciao,
Fabio De Francesco
Jul 22 '05 #8
fm**@tiscali.it (fabio de francesco) wrote in
news:ba*************************@posting.google.co m:
If it is "...just as it would if you passed it to a function by
value." why passing an object to a function by value makes only a
single copy, whereas we have two copies with "throw-catch"?


It is only one in each case. The second copy in your example (the first
chronologically) occurs because in your fun_2 function you are creating
throwing in two discrete steps rather than one.
Instead of

catch (Object obj)

try

catch (const Object& obj)


I already know. This is not the point.
The first copy is made when you are throwing the non-temporary local
object.


And the second one?


The second one is the catch by value. If you did this

throw Object("local object");

rather than

Object Thrown("local object");
throw Thrown;

I think you would see only one copy construction.

Gregg
Jul 22 '05 #9
Gregg <gr***@invalid.invalid> wrote in message news:<Xn********************************@207.69.15 4.203>...
fm**@tiscali.it (fabio de francesco) wrote in
news:ba*************************@posting.google.co m:
If it is "...just as it would if you passed it to a function by
value." why passing an object to a function by value makes only a
single copy, whereas we have two copies with "throw-catch"?


It is only one in each case. The second copy in your example (the first
chronologically) occurs because in your fun_2 function you are creating
throwing in two discrete steps rather than one.
Instead of

catch (Object obj)

try

catch (const Object& obj)


I already know. This is not the point.
The first copy is made when you are throwing the non-temporary local
object.


And the second one?


The second one is the catch by value. If you did this

throw Object("local object");

rather than

Object Thrown("local object");
throw Thrown;

I think you would see only one copy construction.

Gregg


Thank you Gregg,
this is exactily what triggered the second copy-construction. I didn't
imagine that splitting the creation of the object to be thrown in two
discrete steps would had required the use of two different
constructions; for this reasons I imagined that the second copy was
made by the thrown-catch mechanism itself.

Ciao,
Fabio De Francesco
Jul 22 '05 #10

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

Similar topics

8
by: Thomas Mlynarczyk | last post by:
Hi! If A is an object, then "B = A;" will just assign a reference. Isn't there a simple way to create an actual copy of A and assign that to B? Greetings, Thomas
9
by: Aguilar, James | last post by:
Hey guys. A new question: I want to use an STL libarary to hold a bunch of objects I create. Actually, it will hold references to the objects, but that's beside the point, for the most part. ...
10
by: Jax | last post by:
I dont seem to fully comprehend references to objects yet. Lets say for example I do this; Customer c = new Customer(); Customer c1 = c; I understand that if I change c1, I also change c as...
14
by: luis | last post by:
Are basic types (int, long, ...) objetcs or not? I read that in C# all are objects including basic types, derived from Object class. Then in msdn documentation says that boxing converts basic...
1
by: Matt | last post by:
Hi all, I have a application that is built in .net. When I run the .exe file I get the following error "Exception has been thrown by the target of an invocation" Now for a little history. I...
15
by: Christopher Benson-Manica | last post by:
Is there a general mechanism to duplicate, or provide for the duplication of, objects? As an example, suppose I need to duplicate an array. I can accomplish this with array.slice( 0 ), but that's...
10
by: =?Utf-8?B?am9uaWdy?= | last post by:
New to VB.NET, designing my first form with an MS manual at my side, placing objects and writing code. For good reason I just: SAVED All (!!) deleted all objects leaving only a grey form,...
16
by: Lamont Sanford | last post by:
I can't figure out why once or twice per week, my C# server application throws OutOfMemoryExceptions. There is plenty of memory in the machine. As far as I can tell, when the exception is thrown,...
3
by: Jon Slaughter | last post by:
What is the general procedure to optimize hit tests on objects with a mouse cursor? Just loop through all the objects and check for intersection and break when found or is there something better? ...
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: 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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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.