Re: exception handling, function call and memory
"Igor Tandetnik" <itandetnik@mvps.org> wrote in message
news:%23d3mnR3YIHA.4208@TK2MSFTNGP04.phx.gbl...
Ben Voigt [C++ MVP] <rbv@nospam.nospam> wrote:
Where do you think exception() object itself lives - parallel
dimension? Plus, as I said, there's a stack frame established for
the try block, in addition to one for the function call.
I'm not necessarily convinced of this... the compiler has full
knowledge of all local variables which may need destruction on entry
to the catch block, it doesn't need to actually use a stack frame. The
fact that you can't combine SEH __except/__finally and C++ catch
in the same function, but you can call between functions with
different handlers, suggests to me that the try block does not, in
fact, create a new stack frame, and a new stack frame is needed when
mixing exception paradigms.
I was under impression that the way stack unwindind code finds a matching
catch clause is because some kind of a marker is created on the stack by
try/catch. This is what I meant by "try block stack frame" (which is
probably quite different from function stack frame of "push ebp; mov ebp,
esp" variety). If I remember correctly, the try/catch stack frames form a
linked list on the stack (every frame points up the stack to the enclosing
frame), and when the exception is thrown, it walks this list to find a
matching handler.
I've never studied the implementation of exceptions in detail though. I
may be completely wrong.
Now I understand what you meant, though I think you'll agree that what you
actually said ("there's a stack frame established for the try block, in
addition to one for the function call") is referring to a function stack
frame.
What you've described is exactly how I would do exception handling if I were
implementing it from scratch, but I think the actual Microsoft
implementation takes error handling out of the fast execution path. That's
why using exceptions is actually more efficient than checking return values
against error codes, as long as exceptions are rare.
I heard somewhere that there's a table used during unwinding which matches
program counter to the list of handlers, as well as type and relative stack
locations for each auto variable requiring destruction. I think by walking
the stack during the search for the exception handler, and accessing data
structures built at compile-time, the C++ exception handling mechanism
actually entirely avoids the runtime costs associated with managing an
exception handler stack, which is to say, with /EHa there's one SEH
exception handler added to the OS handler stack by the CRT at thread
initialization and no additional stack entries are needed.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925