Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Exception Propagation / Copy Constructors

Reply
Thread Tools

Exception Propagation / Copy Constructors

 
 
better_cs_now@yahoo.com
Guest
Posts: n/a
 
      06-18-2009
Hello All,

Please consider the following:

#include <iostream>

using namespace std;

class Foo
{
public:
Foo()
{
cout << "Foo::Foo()" << endl;
}

~Foo()
{
cout << "Foo::~Foo()" << endl;
}

Foo(const Foo &)
{
cout << "Foo::Foo(const Foo &)" << endl;
}
};

void func3()
{
throw Foo();
}

void func2()
{
func3();
}

void func1()
{
func2();
}

int main()
{
try
{
func1();
}
catch(const Foo &)
{
cout << "Caught Foo" << endl;
}
}

This results in the following output:

Foo::Foo()
Caught Foo
Foo::~Foo()

This shows that the copy constructor does not run. Yet, if I make the
copy constructor private, the compiler balks with the following:

main.cpp: In function `void func3()':
main.cpp:20: error: `Foo::Foo(const Foo&)' is private
main.cpp:27: error: within this context
main.cpp:20: error: `Foo::Foo(const Foo&)' is private
main.cpp:27: error: within this context

This leads to two questions:

1. Why does the compiler balk about inaccessibility of a function (the
copy constructor) it does not use?

2. Why *is* it not using the copy constructor? I would have expected
to see the exception object copy constructed / destructed at each
level of the call stack as that stack is unwound.

Thanks,
Dave
 
Reply With Quote
 
 
 
 
pankaj
Guest
Posts: n/a
 
      06-18-2009
On Jun 18, 11:15*am, "better_cs_...@yahoo.com"
<better_cs_...@yahoo.com> wrote:
> Hello All,
>
> Please consider the following:
>
> #include <iostream>
>
> using namespace std;
>
> class Foo
> {
> * *public:
> * * * Foo()
> * * * {
> * * * * *cout << "Foo::Foo()" << endl;
> * * * }
>
> * * * ~Foo()
> * * * {
> * * * * *cout << "Foo::~Foo()" << endl;
> * * * }
>
> * * * Foo(const Foo &)
> * * * {
> * * * * *cout << "Foo::Foo(const Foo &)" << endl;
> * * * }
>
> };
>
> void func3()
> {
> * *throw Foo();
>
> }
>
> void func2()
> {
> * *func3();
>
> }
>
> void func1()
> {
> * *func2();
>
> }
>
> int main()
> {
> * *try
> * *{
> * * * func1();
> * *}
> * *catch(const Foo &)
> * *{
> * * * cout << "Caught Foo" << endl;
> * *}
>
> }
>
> This results in the following output:
>
> Foo::Foo()
> Caught Foo
> Foo::~Foo()
>
> This shows that the copy constructor does not run. Yet, if I make the
> copy constructor private, the compiler balks with the following:
>
> main.cpp: In function `void func3()':
> main.cpp:20: error: `Foo::Foo(const Foo&)' is private
> main.cpp:27: error: within this context
> main.cpp:20: error: `Foo::Foo(const Foo&)' is private
> main.cpp:27: error: within this context
>
> This leads to two questions:
>
> 1. Why does the compiler balk about inaccessibility of a function (the
> copy constructor) it does not use?
>
> 2. Why *is* it not using the copy constructor? I would have expected
> to see the exception object copy constructed / destructed at each
> level of the call stack as that stack is unwound.
>
> Thanks,
> Dave


I think the compiler is doing an optimization here by not creating and
destroying temporary object. The copy constructor still needs to be
accessible, because the optimization is compiler's choice and not a
mandatory behavior.
 
Reply With Quote
 
 
 
 
Richard Herring
Guest
Posts: n/a
 
      06-18-2009
In message
<f44b3a24-54c2-46f7-b33b->,
"" <> writes
>Hello All,
>
>Please consider the following:
>
>#include <iostream>
>
>using namespace std;
>
>class Foo
>{
> public:
> Foo()
> {
> cout << "Foo::Foo()" << endl;
> }
>
> ~Foo()
> {
> cout << "Foo::~Foo()" << endl;
> }
>
> Foo(const Foo &)
> {
> cout << "Foo::Foo(const Foo &)" << endl;
> }
>};
>
>void func3()
>{
> throw Foo();
>}
>
>void func2()
>{
> func3();
>}
>
>void func1()
>{
> func2();
>}
>
>int main()
>{
> try
> {
> func1();
> }
> catch(const Foo &)
> {
> cout << "Caught Foo" << endl;
> }
>}
>
>This results in the following output:
>
>Foo::Foo()
>Caught Foo
>Foo::~Foo()
>
>This shows that the copy constructor does not run. Yet, if I make the
>copy constructor private, the compiler balks with the following:
>
>main.cpp: In function `void func3()':
>main.cpp:20: error: `Foo::Foo(const Foo&)' is private
>main.cpp:27: error: within this context
>main.cpp:20: error: `Foo::Foo(const Foo&)' is private
>main.cpp:27: error: within this context
>
>This leads to two questions:
>
>1. Why does the compiler balk about inaccessibility of a function (the
>copy constructor) it does not use?


Because, among other things, deliberately making it inaccessible is a
common way of preventing an object being copied. Not enforcing the
accessibility rule merely because of a compiler optimization would break
that.
>
>2. Why *is* it not using the copy constructor? I would have expected
>to see the exception object copy constructed / destructed at each
>level of the call stack as that stack is unwound.


Why would you expect that, and what use would it be? Notionally, throw
Foo() initializes a temporary (15.1/3) (which is why an accessible copy
ctor is required) which gets passed directly to the catch block. It's
only automatic objects which get destroyed as the stack unwinds.

--
Richard Herring
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      06-18-2009
wrote:
> 1. Why does the compiler balk about inaccessibility of a function (the
> copy constructor) it does not use?


Because the standard requires the copy constructor to be accessible
even though it specifically allows the compiler to skip calling it.

There's a much simpler situation with the same requirements: Suppose
that you have a class named MyClass with a constructor which takes an
int. If you do this:

MyClass obj = 5;

then the copy constructor of MyClass must be accessible even though the
compiler is allowed to never call it. Test it if you like.

> 2. Why *is* it not using the copy constructor? I would have expected
> to see the exception object copy constructed / destructed at each
> level of the call stack as that stack is unwound.


The compiler is allowed to optimize copy constructor calls away if it
can, even in situations where it should "logically" be called. The
standard specifically gives this permission. In this particular
situation the compiler uses some smart optimization to avoid useless
copy constructor calls.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
reg constructors/copy constructors inheritance srp113 C++ 3 02-17-2009 04:01 PM
Tool for static analysis of C++ exception propagation Brendon Costa C++ 0 11-03-2007 10:23 AM
compiler synthesized constructors/copy constructors/assignment operators Jess C++ 5 06-07-2007 11:09 AM
Copy constructors, de/constructors and reference counts Jeremy Smith C++ 2 08-02-2006 11:25 PM
RMI Boundary, Package Visibility, and Exception Propagation robertbrown1971@yahoo.com Java 5 08-26-2005 05:19 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57