Exception Misconceptions

D

dragan

I got the idea and material for this thread from the "high-class" ( ;) ) ng
clc++m. Please add any commonly held/observed misconceptions about C++
exceptions or exceptions in general. Both mechanism and condition
misconceptions are fine. I'll start...

"Exceptions invoke all destructors while unwinding the stack."

I think that is probably incorrect, though I'm not a compiler writer so
can't say with high certainty that it is a misconception. I hypothesize that
the compiler introduces some kind of "jumps to the closing brace" and lets
the normal destruction of stack class objects happen. An explicit mechanism
that is part of the exception machinery that calls destructors? I don't
think so.
 
A

Armel

dragan said:
I got the idea and material for this thread from the "high-class" ( ;) ) ng
clc++m. Please add any commonly held/observed misconceptions about C++
exceptions or exceptions in general. Both mechanism and condition
misconceptions are fine. I'll start...

"Exceptions invoke all destructors while unwinding the stack."

I think that is probably incorrect, though I'm not a compiler writer so
can't say with high certainty that it is a misconception. I hypothesize
that the compiler introduces some kind of "jumps to the closing brace" and
lets the normal destruction of stack class objects happen. An explicit
mechanism that is part of the exception machinery that calls destructors?
I don't think so.
don't know exactly, but that is no obvious at all, "jumping to the closing
brace" is not what you want to do: the return intruction would then be
executed, returning to the normal flow of program. you don't want that;
unless you have a special end of function testing if in normal or "exception
rewind" mode. most compilers will not want the penalty of this test.

if you want more insight on this question, you could ask on comp.compilers.

Regards
Armel
 
B

Bart van Ingen Schenau

I got the idea and material for this thread from the "high-class" ( ;) ) ng
clc++m. Please add any commonly held/observed misconceptions about C++
exceptions or exceptions in general. Both mechanism and condition
misconceptions are fine. I'll start...

"Exceptions invoke all destructors while unwinding the stack."

I think that is probably incorrect, though I'm not a compiler writer so
can't say with high certainty that it is a misconception. I hypothesize that
the compiler introduces some kind of "jumps to the closing brace" and lets
the normal destruction of stack class objects happen. An explicit mechanism
that is part of the exception machinery that calls destructors? I don't
think so.

And how does the mechanism that you describe fail to invoke the
destructors of the relevant stack-allocated objects?

The requirement is that all the objects that go out of scope as a
result of the jump from the throw statement to the catch handler must
be properly destructed. It does not matter what hoops the compiler
writer has to jump through to fulfill the requirement.
This could be a separate piece of code that consists only of
destructor calls (which means that for every object, there are at
least two sites from which the destructor can be called), or a scheme
like you describe. It is the end-result that matters.

Bart v Ingen Schenau
 
J

James Kanze

I got the idea and material for this thread from the
"high-class" ( ;) ) ng clc++m. Please add any commonly
held/observed misconceptions about C++ exceptions or
exceptions in general. Both mechanism and condition
misconceptions are fine. I'll start...
"Exceptions invoke all destructors while unwinding the stack."
I think that is probably incorrect,

Well, certainly not all destructors. Just those of variables
which go out of scope.
though I'm not a compiler writer so can't say with high
certainty that it is a misconception. I hypothesize that the
compiler introduces some kind of "jumps to the closing brace"
and lets the normal destruction of stack class objects happen.
An explicit mechanism that is part of the exception machinery
that calls destructors? I don't think so.

You hypothesize wrong. The usual implementation (except maybe
for Microsoft) is to generate tables mapping code addresses to
clean up functions; the exception propagation code (in the
library) finds the frame pointer from the stack, uses the table
to find the clean up code, and calls it, for each stack frame.
I think some earlier compilers generated additional code in the
constructor to "register" the class, but the table method is
generally considered preferable, as it has almost no runtime
overhead until the exception is thrown.
 
D

dragan

Bart said:
And how does the mechanism that you describe fail to invoke the
destructors of the relevant stack-allocated objects?

It doesn't do it explicitly with a mechanism separate from the mechanism(s)
that are used even in the no-throw function.
The requirement is that all the objects that go out of scope as a
result of the jump from the throw statement to the catch handler must
be properly destructed. It does not matter what hoops the compiler
writer has to jump through to fulfill the requirement.

To YOU it doesn't matter you mean. Enquiring minds wanna know!
This could be a separate piece of code that consists only of
destructor calls (which means that for every object, there are at
least two sites from which the destructor can be called), or a scheme
like you describe. It is the end-result that matters.

To YOU it is all that matters. Try stepping out of your own skin sometime.
 
D

dragan

James said:
You hypothesize wrong. The usual implementation (except maybe
for Microsoft) is to generate tables mapping code addresses to
clean up functions; the exception propagation code (in the
library) finds the frame pointer from the stack, uses the table
to find the clean up code, and calls it, for each stack frame.
I think some earlier compilers generated additional code in the
constructor to "register" the class, but the table method is
generally considered preferable, as it has almost no runtime
overhead until the exception is thrown.

What is the mechanism and how does it work in the no-throw function case?
 
J

James Kanze

What is the mechanism and how does it work in the no-throw
function case?

The mechanism is more or less what I described: for each
distinct set of objects to clean up, the compiler generates a
clean-up function, and puts its address in a table along with
the code addresses for which this function is valid. (This code
can be destructors or catch blocks. In the latter case, the
compiler also provides information concerning the types for
which the try block is valid.) When an exception is thrown, the
compiler calls code which walks back up the stack. For each
return address it finds, it looks up in the table what it has to
do, and does it.

Typically, the case of nothrow is treated by generating the same
code as if the function were wrapped in a try block, and
handling the error in a catch.

Other solutions are possible. Microsoft, for example, seems to
generate code which is executed in the case where the exception
isn't thrown, although I don't know what it's exact role is.
 
A

aku ankka

Bart van Ingen Schenau wrote:







It doesn't do it explicitly with a mechanism separate from the mechanism(s)
that are used even in the no-throw function.




To YOU it doesn't matter you mean. Enquiring minds wanna know!

This is implementation specific detail, if you know how it works in,
for example, GCC 4.5 doesn't say anything about how it works in the
Visual Studio 2010. What matters, is that the compiler is conforming
to the standard.

Enquiring minds can use /Faout.asm or -S out.s compiler switch (or
equivalent) but that is compiler/toolchain specific knowledge.

To YOU it is all that matters. Try stepping out of your own skin sometime..-

That's correct. He was speaking for himself and the statement is 100%
accurate. Wow, you can read; that's very impressive!

=)
 
D

dragan

aku said:
This is implementation specific detail, if you know how it works in,
for example, GCC 4.5 doesn't say anything about how it works in the
Visual Studio 2010.

That is understood. That doesn't stop me wanting to know how it works
though. Don't you have something better to do that to try to curb someone's
appetite for knowledge?
What matters, is that the compiler is conforming
to the standard.

To YOU. Why don't you start your own threads about stuff you wanna know and
stay out of mine? Because you add no value!
Enquiring minds can use /Faout.asm or -S out.s compiler switch (or
equivalent) but that is compiler/toolchain specific knowledge.

Luckily, JK was cordial enough to answer the question instead of starting a
tirade of what is "on holy topic" and the like in this NG. :p
That's correct. He was speaking for himself and the statement is 100%
accurate. Wow, you can read; that's very impressive!

Just go away you big baby!
 
D

dragan

James said:
The mechanism is more or less what I described:

Are you saying that there then is NOT a distinct mechanism for exceptions
that does unwinding?
for each
distinct set of objects to clean up, the compiler generates a
clean-up function, and puts its address in a table along with
the code addresses for which this function is valid.

I hypothesized that there was no mechanism, separate from the case where
there are no exception elements in the code, (read NOT TWO mechanisms) to do
unwind explicitly for exceptions and tied explicitly ('distinctly' may be a
better word) to the exception machinery. Is that hypothesis right or wrong?
(This code
can be destructors or catch blocks. In the latter case, the
compiler also provides information concerning the types for
which the try block is valid.) When an exception is thrown, the
compiler calls code which walks back up the stack. For each
return address it finds, it looks up in the table what it has to
do, and does it.

Typically, the case of nothrow is treated by generating the same
code as if the function were wrapped in a try block, and
handling the error in a catch.

Other solutions are possible. Microsoft, for example, seems to
generate code which is executed in the case where the exception
isn't thrown, although I don't know what it's exact role is.

It sounds like I was right then.
 
N

Nick Keighley

you'd find life smoother if you lost a bit of attitude...


just read the standard then you'd know what an implementation is
required to do. The dtors for all objects that go out of scope must be
invoked.


I fail to see the difference. How does your mechanism handle this:

void photon (int x)
{
Fred fred (x);
fred.process(); /* this throws */
George g;
g.process();
}

why isn't g's destructor invoked?

as described above?


no destructors are invoked in the nothrow case?

Are you saying that there then is NOT a distinct mechanism for exceptions
that does unwinding?

there is a description in the standard that specifies in what
circumstances unwinding is done. How the implementor achieves this is
up to him. Most programming languages work like this.

b = a * 2;

might use an add instruction. Or it might use a shift. You don't care
so long as it gets the right answer.

Since Bjarne Stroustrup was a practical man he didn't specify things
that were unimplementable. I think pretty well everyone does virtual
functions the same way, though the standard doesn't mandate it. I
understand there is more variety in the implementation of exceptions.

I you want assembler you know where to find it!

I hypothesized that there was no mechanism, separate from the case where
there are no exception elements in the code, (read NOT TWO mechanisms) to do
unwind explicitly for exceptions and tied explicitly ('distinctly' may be a
better word) to the exception machinery. Is that hypothesis right or wrong?

there is no madatory mechanism defined by the standard. Some
implementations use what you call "a mechanism". I don't understand
why you care or what you are tryign to make.
It sounds like I was right then.

hasn't he just described "a mechanism"? Doesn't that mean you were
wrong?
 
J

James Kanze

Are you saying that there then is NOT a distinct mechanism for
exceptions that does unwinding?

What do you mean by "distinct mechanism"? Every compiler (or
sometimes the platform ABI) defines a mechanism to be used.
What has to happen is specified by the standard; how the
compiler achieves this is unspecified.
I hypothesized that there was no mechanism, separate from the
case where there are no exception elements in the code, (read
NOT TWO mechanisms) to do unwind explicitly for exceptions and
tied explicitly ('distinctly' may be a better word) to the
exception machinery. Is that hypothesis right or wrong?

$ don't understand what you're hypothesising. The compiler has
to generate something to handle exceptions in order to be
conform. The standard says what the observable behavior must
be, not what the compiler does to achieve that.
It sounds like I was right then.

Right about what? You said that you thought "Exceptions invoke
all destructors while unwinding the stack" was probably
incorrect---if you meant "all destructors of objects which cease
to be in scope", the statement is correct, and you're wrong.
You hypothesized that the compiler introduces some kind of
`jumps to the closing brace' and lets the normal destruction of
stack class objects happen": this hypothesis is wrong, at least
for the compilers I know. You also said "An explicit mechanism
that is part of the exception machinery that calls destructors?
I don't think so." I'm not sure what you mean by that, but the
compiler definitely does generate code which is specific to
exception handling, and it is that code which calls the
destructors.
 
D

dragan

Nick said:
you'd find life smoother if you lost a bit of attitude...

??? What are you talking about?
just read the standard then you'd know what an implementation is
required to do. The dtors for all objects that go out of scope must be
invoked.

Though the one who I quoted was thinking, surely, at the standard level, I
was relating it to the implementation/mechanism level and is still where the
focus of discussion is. All else is is off-topic for it is not relevant to
the "question" posed. Do you see?
I fail to see the difference.

Me too. That's why I hypothesize that there is no separate mechanism tied to
the exception machinery (unless you want to call the exception machinery the
lower level concept). When using a compiler switch to turn off exceptions,
what happens under the covers?
How does your mechanism handle this: [example omitted]

(Joke spared, but it was waaay funny!). (OK, I was about to write: "_I_
don't have a mechanis...", and then I had to package it differently.) (See,
it never ends! he he he he! ). (Waaay funny IMO).

Seriously now, I'm not a compiler writer so if such a thing as I IMAGINED
exists, you'll have to ask the one who implemented it.
as described above?

You can't extract just that portion of the sentence and get the same
meaning. Why did you do that? It is REQUIRED to read to the sentence
terminator to comprehend the thought. Periods and other sentence terminators
are not there only for decorative purposes, you know.
no destructors are invoked in the nothrow case?

When stack class objects go out of scope, their destructors are called. You
know that. I know you do. (Don't you?).
there is a description in the standard that specifies in what
circumstances unwinding is done.

The topic is the underlying mechanisms of implementation, NOT the
standard-level operation. You must have missed that very important element:
the topic of discussion. (It could be my bad English?).
I you want assembler you know where to find it!

And if you have nothing to say that is relevant to the discussion, you know
what not to do.
there is no madatory mechanism defined by the standard.

The "question" had nothing to do with the standard. Hello?
Some
implementations use what you call "a mechanism". I don't understand
why you care or what you are tryign to make.

JK was doing a fine job at describing the underpinnings of a typical
implementation. I think this is an area where you should bow out and let JK
continue, for he has the requisite knowledge and information being sought:
aka, "the answer".
hasn't he just described "a mechanism"? Doesn't that mean you were
wrong?

Until I see 2 distinct mechanisms, I am right.
 
D

dragan

James said:
What do you mean by "distinct mechanism"? Every compiler (or
sometimes the platform ABI) defines a mechanism to be used.
What has to happen is specified by the standard; how the
compiler achieves this is unspecified.

Oh you too now?? The question at hand IS the mechanisms, NOT an operational
standard. And you know this because your prior post shows that you do
because you gave a description of the mechanism: tables, cleanup functions,
etc. The hypothesis is that all that stuff you mentioned is the
implementation of how classes work when leaving a scope and that there is no
separate machinery to do that for exceptions.
$ don't understand what you're hypothesising.

See above. You seemed pretty sure that I was hypothesizing wrongly though
just a few posts ago. "Things that make you say 'hmmm'".
The compiler has
to generate something to handle exceptions in order to be
conform. The standard says what the observable behavior must
be, not what the compiler does to achieve that.

The standard has only remote association to the issue at hand.
Right about what?

My hypothesis.
You said that you thought "Exceptions invoke
all destructors while unwinding the stack" was probably
incorrect

Yes, but the key concept of the hypothesis is that there is no separate
mechanism to do the unwinding tied to the exception machinery.
---if you meant "all destructors of objects which cease
to be in scope", the statement is correct, and you're wrong.
You hypothesized that the compiler introduces some kind of
`jumps to the closing brace' and lets the normal destruction of
stack class objects happen"

That was just an imagined thing. I noted that I am not a compiler writer.
That did scare me off from venturing a WAG on how it is done. And that is
not important to the hypothesis, nor is it the hypothesis, but I get the
feeling you would like to try to make it seem like it was? The childish
antics in language groups are phenomenal! They never cease to amaze me.
: this hypothesis is wrong, at least
for the compilers I know. You also said "An explicit mechanism
that is part of the exception machinery that calls destructors?
I don't think so." I'm not sure what you mean by that,

How convenient for you, since that IS the hypothesis.
but the
compiler definitely does generate code which is specific to
exception handling, and it is that code which calls the
destructors.

I guess at this point, nothing else will do except a side-by-side comparison
analysis of the actual processes and mechanisms of an implementation (or a
few implementations). Thanks for trying to explain it though.
 
A

aku ankka

Luckily, JK was cordial enough to answer the question instead of starting a
tirade of what is "on holy topic" and the like in this NG. :p

I'm sorry I am not going to divulge any intellectual property /
patentable technology, but if you want to see how a specific compiler
does it you can check the compiler output. You will see easily how the
exception handling is implemented.

Just go away you big baby!- Hide quoted text -

What's more impressive is that you also seem to be able to write!
 
A

aku ankka

I guess at this point, nothing else will do except a side-by-side comparison
analysis of the actual processes and mechanisms of an implementation (or a
few implementations). Thanks for trying to explain it though.-

That's the whole point. From the language/standard point of view the
topic is not relevant or interesting. You can discuss the mechanism in
context of some specific implementation. Until the specific
implementation is established the best you or anyone else can do is
to discuss what the exceptions should do.


The c++ has exceptions. Yes/No?

They are supposed to work as specified. True/False?

In absense of any specific compiler or toolchain mentioned, you choose
to completely ignore the fact that you can find out yourself by
inspecting the compiler's output.
 
J

James Kanze

[...]
How convenient for you, since that IS the hypothesis.
I guess at this point, nothing else will do except a
side-by-side comparison analysis of the actual processes and
mechanisms of an implementation (or a few implementations).
Thanks for trying to explain it though.

The real problem I'm having, I think, is in understanding what
you mean by "an explicit mechanism". Within the compiler (and
the compiler's runtime library), there is a lot of code which
deals exclusively in exceptions: the tables generated in my
explination are only used in exception handling, the code
which walks back the stack, looking for the return addresses in
the tables is only used for exception handling, and the separate
clean-up routines called by that code are only used for
exception handling. To me, that's a "mechanism", and it is
explicitly used for exceptions. But maybe you're thinking of
something else with regards to "mechanism".
 
S

Squeamizh

??? What are you talking about?

He means you're a total douchebag, and he's right. I do think the
responses that actually answer your question are interesting and
worthwhile, however.
 
D

dragan

James said:
James said:
James Kanze wrote:
[...]
this hypothesis is wrong, at least
for the compilers I know. You also said "An explicit mechanism
that is part of the exception machinery that calls destructors?
I don't think so." I'm not sure what you mean by that,
How convenient for you, since that IS the hypothesis.
I guess at this point, nothing else will do except a
side-by-side comparison analysis of the actual processes and
mechanisms of an implementation (or a few implementations).
Thanks for trying to explain it though.

The real problem I'm having, I think, is in understanding what
you mean by "an explicit mechanism". Within the compiler (and
the compiler's runtime library), there is a lot of code which
deals exclusively in exceptions: the tables generated in my
explination are only used in exception handling, the code
which walks back the stack, looking for the return addresses in
the tables is only used for exception handling, and the separate
clean-up routines called by that code are only used for
exception handling. To me, that's a "mechanism", and it is
explicitly used for exceptions. But maybe you're thinking of
something else with regards to "mechanism".

Yes, you understand "mechanism" the same way as I used it (and no need to
get into the plural of the term, as this is not an English language learning
newsgroup though at times it sure feels like it). "Umpteen" posts ago, you
told of that mechanism and I asked then what is the mechanism and processing
like in the case where there are no exceptions, say the compiler switch that
turns off exception handling is on. So far, we have the one mechanism
"defined" (for some whatever implementation) and now I'm in search of the
other one for comparison. I meant "explicit" as "separate from the mechanism
that calls destructors and controls program flow in the case where there are
no exceptions". 'explicit' was probably a bad word choice, though how what
info was being sought couldn't be clear given all the context, baffles me.
(Aside: "mechanism" applied to software code may be a bit of a stretch for
some minds uninitiated to anything other than the narrow world of software
development. Another hypothesis in the making.)
 
J

Jorgen Grahn

That is understood. That doesn't stop me wanting to know how it works
though. Don't you have something better to do that to try to curb someone's
appetite for knowledge?

Your first posting started out with mentioning "commonly held/observed
misconceptions" so I guess most of us assumed you were talking about
the things that matter when *using* the language. That's why you got
the kinds of answers you got.

I also don't see how you can interpret those answers as attempts to
curb your appetite for knowledge.

....
To YOU. Why don't you start your own threads about stuff you wanna know and
stay out of mine? Because you add no value! ....
Just go away you big baby!

I don't have time for this.

*PLONK*
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top