Topic: a question about temporary exception object
Author: nimel@hem1.passagen.se
Date: 1998/11/07 Raw View
In article <3642A62C.CF2FC315@ccnet.com>,
Gilbert Chang <gchang@ccnet.com> wrote:
>
> According to the standard, the constructor and the destructor of Foo
> should be called exactly once for each in the first case, but they could
> be called either once for each or twice for each. Is my understanding
> correct?
>
> I experimented with VC++6.0. In both cases, the constructor was called
> once, but the destructor was called twice. Did I do something wrong or
> is the compiler simply broken?
I tried the same thing on VC++ 6.0. For me both the constructor and
the destructor was called once when catching by reference, and
twice when catching by value. My guess is that you forgot to count
the copy constructor. Below is the output from my test:
begin
throwing Foo
Foo ctor
caught Foo&
Foo dtor
throwing Foo
Foo ctor
Foo copy ctor
caught Foo
Foo dtor
Foo dtor
end
/Niklas Mellin
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Gilbert Chang <gchang@ccnet.com>
Date: 1998/11/06 Raw View
<quote from the C++ standard draft>
The memory for the temporary copy of the exception being thrown is
allocated in an unspecified way, except as noted in
_basic.stc.dynamic.allocation_. The temporary persists as long as
there is a handler being executed for that exception. In particular,
if a handler exits by executing a throw; statement, that passes con-
trol to another handler for the same exception, so the temporary
remains. If the use of the temporary object can be eliminated without
changing the meaning of the program except for the execution of con-
structors and destructors associated with the use of the temporary
object (_class.temporary_), then the exception in the handler can be
initialized directly with the argument of the throw expression. When
the thrown object is a class object, and the copy constructor used to
initialize the temporary copy is not accessible, the program is ill-
formed (even when the temporary object could otherwise be eliminated).
Similarly, if the destructor for that object is not accessible, the
program is ill-formed (even when the temporary object could otherwise
be eliminated).
<end of quote>
Consider the following code snippets:
//
// class Foo
// {
// public:
// Foo();
// ~Foo();
// };
//
try
{
throw Foo();
}
catch(Foo & foo)
{
}
VS.
try
{
throw Foo();
}
catch(Foo foo)
{
}
According to the standard, the constructor and the destructor of Foo
should be called exactly once for each in the first case, but they could
be called either once for each or twice for each. Is my understanding
correct?
I experimented with VC++6.0. In both cases, the constructor was called
once, but the destructor was called twice. Did I do something wrong or
is the compiler simply broken?
Thanks
Gilbert Chang
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/06 Raw View
In article <3642A62C.CF2FC315@ccnet.com>, Gilbert Chang
<gchang@ccnet.com> writes
>I experimented with VC++6.0. In both cases, the constructor was called
>once, but the destructor was called twice. Did I do something wrong or
>is the compiler simply broken?
Did you instrument the copy ctor? (because forgetting that is the
commonest cause for an apparent mismatch between documented ctors and
dtors)
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: 1998/11/07 Raw View
>
> I experimented with VC++6.0. In both cases, the constructor was called
> once, but the destructor was called twice. Did I do something wrong or
> is the compiler simply broken?
>
I'm only running VC++ 5, but is it perhaps that you forgot
to put a print in your copy constructor? I compiled your
test with my own Foo class with prints in the constructors
and destructors and got this:
Foo()
CAUGHT
~Foo()
Foo()
Foo(Foo&)
CAUGHT
~Foo()
~Foo()
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: AllanW@my-dejanews.com
Date: 1998/11/07 Raw View
In article <3642A62C.CF2FC315@ccnet.com>,
Gilbert Chang <gchang@ccnet.com> wrote:
> // class Foo
> // {
> // public:
> // Foo();
ADD: Foo(const Foo&);
> // ~Foo();
> // };
> //
>
> try
> {
> throw Foo();
> }
> catch(Foo & foo)
> {
> }
>
> VS.
>
> try
> {
> throw Foo();
> }
> catch(Foo foo)
> {
> }
>
> I experimented with VC++6.0. In both cases, the constructor was called
> once, but the destructor was called twice. Did I do something wrong or
> is the compiler simply broken?
Give Foo a copy constructor, as shown above. The default
constructor was called once, the copy constructor was called
once, and both copies were eventually destructed. This is
correct behavior.
As a rule of thumb, always assume you've made a mistake before
you blame the compiler. There are exceptions to that rule, of
course, but the assumption is the safe way to go.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Paul D. DeRocco" <pderocco@ix.netcom.com>
Date: 1998/11/07 Raw View
Gilbert Chang wrote:
>
> Consider the following code snippets:
>
> //
> // class Foo
> // {
> // public:
> // Foo();
> // ~Foo();
> // };
> //
>
> try
> {
> throw Foo();
> }
> catch(Foo & foo)
> {
> }
>
> VS.
>
> try
> {
> throw Foo();
> }
> catch(Foo foo)
> {
> }
>
> According to the standard, the constructor and the destructor of Foo
> should be called exactly once for each in the first case, but they
> could be called either once for each or twice for each. Is my
> understanding correct?
In the most literal sense, with no optimizations, the Foo() should cause
a temporary object to be constructed on the stack. Then the throw should
copy the Foo into some safe memory that is unaffected by the stack
unwinding. Then, in the second case, the catch should copy the object a
third time. However, the standard always allow copies of temporaries to
be optimized away, even if their constructors and destructors are
nontrivial, as long as no other semantic changes result. And in
practice, compilers are smart enough to know that the Foo can originally
be constructed into the safe memory where it will live while the stack
is unwound. In fact, the compiler may even construct the foo directly
into the stack space allocated for foo in the second catch clause.
However, I don't think this is typical.
--
Ciao,
Paul
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]