Dear newsgroup,
In the following code, it looks as though the exception thrown in the
constructor is not caught properly. I get this output:
---- standard output ----
Base() constructor.
Exception in Base(): "Going down (B can't be
construced properly)!"
(the exception has now been dealt with).
main(): We got an exception while constructing B
that already should have been dealt with?
-------------------------
Here is the code:
---- Code ----
#include <iostream>
#include <stdexcept>
class Base
{
public:
Base()
try
{
std::cout << "Base() constructor.\n";
throw std::runtime_error("Going down (B can't be construced "
"properly)!");
}
catch(const std::exception& ex)
{
std::cout << "Exception in Base(): \""
<< ex.what()
<< "\"\n (the exception has now been dealt with).\n";
}
virtual ~Base()
{
std::cout << "~Base()\n";
}
};
int main()
{
try
{
Base B;
}
catch(const std::exception& ex)
{
std::cout << "main(): "
<<"We got an exception while constructing B\n"
" that already should have been dealt with?\n";
}
return 0;
}
---- End-of-Code ----
Anybody have an explanation to why the exception looks to have been
re-thrown?
Sincerely,
Peter Jansson http://www.p-jansson.com/ http://peter.jansson.net/ 11 2189
Peter Jansson wrote:
In the following code, it looks as though the exception thrown in the
constructor is not caught properly. I get this output:
[...]
class Base
{
public:
Base()
try
{
std::cout << "Base() constructor.\n";
throw std::runtime_error("Going down (B can't be construced "
"properly)!");
}
catch(const std::exception& ex)
{
std::cout << "Exception in Base(): \""
<< ex.what()
<< "\"\n (the exception has now been dealt with).\n";
}
virtual ~Base()
{
std::cout << "~Base()\n";
}
};
int main()
{
try
{
Base B;
}
catch(const std::exception& ex)
{
std::cout << "main(): "
<<"We got an exception while constructing B\n"
" that already should have been dealt with?\n";
}
return 0;
}
You can find a very detailed and insightful answer to your question
here: http://www.gotw.ca/gotw/066.htm
--
Christian Hackl
On Jul 31, 10:59*am, Christian Hackl <ha...@sbox.tugraz.atwrote:
Peter Jansson wrote:
In the following code, it looks as though the exception thrown in the
constructor is not caught properly. I get this output:
[...]
class Base
{
* * public:
* * * *Base()
* * * * * try
* * * * * {
* * * * * * *std::cout << "Base() constructor.\n";
* * * * * * *throw std::runtime_error("Going down (B can't be construced "
* * * * * * * * * *"properly)!");
* * * * * }
* * * *catch(const std::exception& ex)
* * * *{
* * * * * std::cout << "Exception in Base(): \""
* * * * * * *<< ex.what()
* * * * * * * * << "\"\n * *(the exception has now been dealt with).\n";
* * * *}
* * * *virtual ~Base()
* * * *{
* * * * * std::cout << "~Base()\n";
* * * *}
};
int main()
{
* * try
* * {
* * * *Base B;
* * }
* * catch(const std::exception& ex)
* * {
* * * *std::cout << "main(): "
* * * * * <<"We got an exception while constructing B\n"
* * * * * * *" * *that already should have been dealtwith?\n";
* * }
* * return 0;
}
You can find a very detailed and insightful answer to your question
here:http://www.gotw.ca/gotw/066.htm
--
Christian Hackl- Hide quoted text -
- Show quoted text -
Interesting that the article contains these statements:
Q: When does an object's lifetime end?
A: When its destructor begins. That is, control reaches
the beginning of the destructor body.
I disagree with the above. If the object no longer exists
starting from the beginning of the destructor body, then
the destructor could not access any of its internal fields.
If that were the case, the existence of the destructor
becomes useless.
The object MUST exist until the final statement of the
destructor is executed.
--
Fred Kleinschmidt
On Thu, 31 Jul 2008, Christian Hackl wrote:
You can find a very detailed and insightful answer to your question here: http://www.gotw.ca/gotw/066.htm
Thank you, that article really cleared it all for me. Basically, the
answer to my question is the following quote from that article:
"What's less obvious, but clearly stated in the standard, is that if the
catch block does not throw (either rethrow the original exception, or
throw something new), and control reaches the end of the catch block of a
constructor or destructor, then the original exception is automatically
rethrown."
Sincerely,
Peter Jansson http://www.p-jansson.com/ http://peter.jansson.net/
On Jul 31, 1:47*pm, Peter Jansson <webmas...@jansson.netwrote:
Dear newsgroup,
In the following code, it looks as though the exception thrown in the
constructor is not caught properly. I get this output:
---- standard output ----
Base() constructor.
Exception in Base(): "Going down (B can't be
construced properly)!"
* * *(the exception has now been dealt with).
main(): We got an exception while constructing B
* * *that already should have been dealt with?
-------------------------
Here is the code:
---- Code ----
#include <iostream>
#include <stdexcept>
class Base
{
* * public:
* * * *Base()
* * * * * try
* * * * * {
* * * * * * *std::cout << "Base() constructor.\n";
* * * * * * *throw std::runtime_error("Going down (B can't be construced "
* * * * * * * * * *"properly)!");
* * * * * }
* * * *catch(const std::exception& ex)
* * * *{
* * * * * std::cout << "Exception in Base(): \""
* * * * * * *<< ex.what()
* * * * * * * * << "\"\n * *(the exception has now been dealt with).\n";
* * * *}
* * * *virtual ~Base()
* * * *{
* * * * * std::cout << "~Base()\n";
* * * *}
};
int main()
{
* * try
* * {
* * * *Base B;
* * }
* * catch(const std::exception& ex)
* * {
* * * *std::cout << "main(): "
* * * * * <<"We got an exception while constructing B\n"
* * * * * * *" * *that already should have been dealt with?\n";
* * }
* * return 0;}
---- End-of-Code ----
Anybody have an explanation to why the exception looks to have been
re-thrown?
It is caught and rethrown, as mandated by the standard (cf. the GOTW
article mentioned above). If you don't want it to be rethrown, put
your try-catch block *in* the constructor body rather than using a
function-try-block *as* the body:
Base::Base()
{ // Note this brace
try
{
std::cout << "Base() constructor.\n";
throw std::runtime_error("Going down (B can't be construced "
"properly)!");
}
catch(const std::exception& ex)
{
std::cout << "Exception in Base(): \""
<< ex.what()
<< "\"\n (the exception has now been dealt with).
\n";
}
} // Note this brace
Cheers! --M
On Thu, 31 Jul 2008, Fred wrote:
[...]
I disagree with the above. If the object no longer exists
starting from the beginning of the destructor body, then
the destructor could not access any of its internal fields.
If that were the case, the existence of the destructor
becomes useless.
The object MUST exist until the final statement of the
destructor is executed.
--
Fred Kleinschmidt
I can not think of any situation where it is interesting to know wether an
object exist or not during it's destruction.
Sincerely,
Peter Jansson http://www.p-jansson.com/ http://peter.jansson.net/
On Thu, 31 Jul 2008, mlimber wrote:
It is caught and rethrown, as mandated by the standard (cf. the GOTW
article mentioned above). If you don't want it to be rethrown, put
your try-catch block *in* the constructor body rather than using a
function-try-block *as* the body:
Yes, that works ok as long as Base is a "first base" class and not
actually derived from some sub base class that throws something during
it's oncstruction.
Sincerely,
Peter Jansson http://www.p-jansson.com/ http://peter.jansson.net/
On 31 Jul., 20:33, Fred <fred.l.kleinschm...@boeing.comwrote:
On Jul 31, 10:59*am, Christian Hackl <ha...@sbox.tugraz.atwrote:
Peter Jansson wrote:
In the following code, it looks as though the exception thrown in the
constructor is not caught properly. I get this output:
[...]
class Base
{
* * public:
* * * *Base()
* * * * * try
* * * * * {
* * * * * * *std::cout << "Base() constructor.\n";
* * * * * * *throw std::runtime_error("Going down (B can't be construced "
* * * * * * * * * *"properly)!");
* * * * * }
* * * *catch(const std::exception& ex)
* * * *{
* * * * * std::cout << "Exception in Base(): \""
* * * * * * *<< ex.what()
* * * * * * * * << "\"\n * *(the exception has now been dealt with).\n";
* * * *}
* * * *virtual ~Base()
* * * *{
* * * * * std::cout << "~Base()\n";
* * * *}
};
int main()
{
* * try
* * {
* * * *Base B;
* * }
* * catch(const std::exception& ex)
* * {
* * * *std::cout << "main(): "
* * * * * <<"We got an exception while constructing B\n"
* * * * * * *" * *that already should have been dealt with?\n";
* * }
* * return 0;
}
You can find a very detailed and insightful answer to your question
here:http://www.gotw.ca/gotw/066.htm
--
Christian Hackl- Hide quoted text -
- Show quoted text -
Interesting that the article contains these statements:
* *Q: When does an object's lifetime end?
* *A: When its destructor begins. That is, control reaches
* * * the beginning of the destructor body.
I disagree with the above. If the object no longer exists
starting from the beginning of the destructor body, then
the destructor could not access any of its internal fields.
If that were the case, the existence of the destructor
becomes useless.
The object MUST exist until the final statement of the
destructor is executed.
No, this is not correct. The initial fields (and base objects) that
get fully constructed will get destructed, but the (nonexisting)
object will not - and this naturally is as it should be.
/Peter
On 2008-07-31 14:55:12 -0400, Peter Jansson <we*******@jansson.netsaid:
On Thu, 31 Jul 2008, mlimber wrote:
>It is caught and rethrown, as mandated by the standard (cf. the GOTW article mentioned above). If you don't want it to be rethrown, put your try-catch block *in* the constructor body rather than using a function-try-block *as* the body:
Yes, that works ok as long as Base is a "first base" class and not
actually derived from some sub base class that throws something during
it's oncstruction.
Exactly. If the base subobject's constructor throws an exception,
there's nothing sensible that the derived type's constructor can do.
--
Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
( www.petebecker.com/tr1book)
On Jul 31, 8:33 pm, Fred <fred.l.kleinschm...@boeing.comwrote:
On Jul 31, 10:59 am, Christian Hackl <ha...@sbox.tugraz.atwrote:
[...]
here:http://www.gotw.ca/gotw/066.htm
Interesting that the article contains these statements:
Q: When does an object's lifetime end?
A: When its destructor begins. That is, control reaches
the beginning of the destructor body.
I disagree with the above.
Then you disagree with the C++ standard, because that's what the
standard says.
If the object no longer exists starting from the beginning of
the destructor body, then the destructor could not access any
of its internal fields. If that were the case, the existence
of the destructor becomes useless.
There are a number of things you can do with an object in the
process of being constructed or destructed. But the C++
standard is clear; the lifetime of the object has ceased.
From the standard's point of view, this is mainly important for
stack unwinding during exception handling. The destructor is
called only on objects whose lifetime has not yet ended; once
you enter the destructor (and until you leave the constructor),
the destructor of that object will not be called. (But
destructors of fully constructed sub-objects will be.)
The object MUST exist until the final statement of the
destructor is executed.
The underlying raw memory must exsit, and the sub-objects must
exist, but the object itself, no.
--
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
In article
<ef**********************************@a1g2000hsb.g ooglegroups.com>, James
Kanze <ja*********@gmail.comwrote:
On Jul 31, 8:33 pm, Fred <fred.l.kleinschm...@boeing.comwrote:
On Jul 31, 10:59 am, Christian Hackl <ha...@sbox.tugraz.atwrote:
[...]
here:http://www.gotw.ca/gotw/066.htm
Interesting that the article contains these statements:
Q: When does an object's lifetime end?
A: When its destructor begins. That is, control reaches
the beginning of the destructor body.
I disagree with the above.
...
The object MUST exist until the final statement of the
destructor is executed.
The underlying raw memory must exsit, and the sub-objects must
exist, but the object itself, no.
It sounds like you're saying that this yields undefined behavior:
struct S
{
virtual void f() { cout << typeid (*this).name(); }
void g() { f(); }
virtual ~S() { g(); }
};
int main() { S s; }
How could the S object's lifetime have ended, yet virtual functions still
work? I obviously need to re-read relevant sections of the standard, but
I'm sure I'm not the only one who finds the above statements surprising,
even if my example program doesn't yield any undefined behavior.
On Aug 1, 5:25 pm, blargg....@gishpuppy.com (blargg) wrote:
In article
<ef422ec9-84d3-4185-9034-752b62d1b...@a1g2000hsb.googlegroups.com>, James
Kanze <james.ka...@gmail.comwrote:
On Jul 31, 8:33 pm, Fred <fred.l.kleinschm...@boeing.comwrote:
On Jul 31, 10:59 am, Christian Hackl <ha...@sbox.tugraz.atwrote:
[...]
here:http://www.gotw.ca/gotw/066.htm
Interesting that the article contains these statements:
Q: When does an object's lifetime end?
A: When its destructor begins. That is, control reaches
the beginning of the destructor body.
I disagree with the above.
...
The object MUST exist until the final statement of the
destructor is executed.
The underlying raw memory must exsit, and the sub-objects must
exist, but the object itself, no.
It sounds like you're saying that this yields undefined
behavior:
struct S
{
virtual void f() { cout << typeid (*this).name(); }
void g() { f(); }
virtual ~S() { g(); }
};
int main() { S s; }
Now where did I say that?
How could the S object's lifetime have ended, yet virtual
functions still work?
Because the standard says that they do. That's really the only
answer I can give. The standard says that for everything
concerning RTTI (dynamic_cast, typeid and virtual function call
resolution), the "object" (whose lifetime has ended) acts as if
it had the type of the destructor being executed.
I obviously need to re-read relevant sections of the standard,
but I'm sure I'm not the only one who finds the above
statements surprising, even if my example program doesn't
yield any undefined behavior.
I'll admit that the standard's wording isn't always the most
intuitive. I think the problem is that it is trying to use a
binary state (alive/dead) for a situation that isn't binary.
The object's "lifetime" starts when the most derived constructor
is finished, and ends when the most derived destructor starts
(see §3.8), but a not yet alive object (or an already dead
object) definitely has certain properties of the object (and not
of just raw memory). Section 3.8 basically says that there are
only a limited set of things that you can do outside of the
lifetime, but in practice, some of them just don't make sense:
according to §3.8, for example, you can't convert a a pointer to
the object to a pointer to the base class. Which taken
literally would mean that you can't call a member function of a
base class from the constructor, because that implies an
implicit conversion of the this pointer to a pointer to the base
class. Note, however, that there are special rules which are in
effect in constructors and destructors, and that some things
that seem like the obviously should work are actually undefined
behavior (and in one case I had, didn't work).
--
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Barry Mossman |
last post by:
Hi,
I am throwing an exception derived from ApplicationException as follows
catch (Exception ex) {
throw new MyException("message", ex);
}
...
|
by: Kevin Yu |
last post by:
is it a bad programming design to throw exception in the try block then
catch it??
|
by: Claudio Di Flumeri |
last post by:
Hello all,
I've added a global exception handler to my application in this way:
Sub Main()
AddHandler Application.ThreadException, AddressOf...
|
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...
|
by: chopsnsauce |
last post by:
Here's the example:
Dim frm As New FORM1
Try
frm.show
Catch ex As Exception
msgbox ex.message
|
by: Neelesh Bodas |
last post by:
Hello all,
Just wanted a small clarification on these two points :
1) The following code compiles well -
int f() try {
throw "xyz";
}...
|
by: junw2000 |
last post by:
Hi,
Below is a simple code about exception.
#include <iostream>
using namespace std;
struct E {
const char* message;
E(const char* arg) :...
|
by: Chris |
last post by:
Hello all...
I have a program with the following structure (all classes
mentioned are of my own creation, and none of the classes contain try
or...
|
by: Rahul |
last post by:
Hi Everyone,
I have the following exception class,
class E1
{
};
class E2
{
|
by: tammygombez |
last post by:
Hey everyone!
I've been researching gaming laptops lately, and I must say, they can get pretty expensive. However, I've come across some great...
|
by: better678 |
last post by:
Question:
Discuss your understanding of the Java platform. Is the statement "Java is interpreted" correct?
Answer:
Java is an object-oriented...
|
by: teenabhardwaj |
last post by:
How would one discover a valid source for learning news, comfort, and help for engineering designs? Covering through piles of books takes a lot of...
|
by: Kemmylinns12 |
last post by:
Blockchain technology has emerged as a transformative force in the business world, offering unprecedented opportunities for innovation and...
|
by: CD Tom |
last post by:
This happens in runtime 2013 and 2016. When a report is run and then closed a toolbar shows up and the only way to get it to go away is to right...
|
by: jalbright99669 |
last post by:
Am having a bit of a time with URL Rewrite. I need to incorporate http to https redirect with a reverse proxy. I have the URL Rewrite rules made...
|
by: antdb |
last post by:
Ⅰ. Advantage of AntDB: hyper-convergence + streaming processing engine
In the overall architecture, a new "hyper-convergence" concept was...
|
by: Matthew3360 |
last post by:
Hi there. I have been struggling to find out how to use a variable as my location in my header redirect function.
Here is my code.
...
|
by: Matthew3360 |
last post by:
Hi, I have a python app that i want to be able to get variables from a php page on my webserver. My python app is on my computer. How would I make it...
| |