views:

1057

answers:

5

Mentally, I've always wondered how try/throw/catch looks behind the scenes, when the C++ compiles translates it to assembler. But since I never use it, I never got around to checking it out (some people would say lazy).

Is the normal stack used for keeping track of try's, or is a separate per-thread stack kept for this purpose alone? Is the implementation between msvc and g++ big or small? Please show me some pseudo asm (IA-32 is ok too) so I never have to check it out myself! :)

Edit: Now I get the basics of MSVC's implementation on IA-32 handling. Anybody know for g++ on IA-32, or any other CPU for that matter?

+11  A: 

This is a very valuable article about the subject: How a C++ compiler implements exception handling

AraK
This article have been published in 2002... is it really up to date?
Klaim
I took an overview long ago. I am not really sure if it is up to date.
AraK
2002 is fairly recent by C++ standards
Javier
Short and to the point. Great complement!
Jonas Byström
A: 

Have a look at this document which describes the internals of exception handling pretty well.

steve
+5  A: 

Microsoft Journal's "Under the Hood" series did an in-depth look at that very subject back in 1997:

A Crash Course on the Depths of Win32™ Structured Exception Handling

Remy Lebeau - TeamB
That covers Windows Structured Exception Handling, which is related to, but not the same as, C++ exception handling. Pietrek mentions in the introduction that C++ exceptions, as implemented by Microsoft and Borland, use SEH, but that his article doesn't cover *how* they implement it.
Rob Kennedy
Great MSVC/IA-32 article, though lengthy.
Jonas Byström
C++ exceptions are just a class of SEH exceptions, with a wrapper to include the C++ information (the exception class instance). C++ exceptions have to use SEH so that they propagate kernel boundaries, etc.
Paul Betts
If you really want to find this out though, it's easy - just trace through it in WinDbg; you can see how the exception mechanisms work (hint: it comes down to kernel32::RaiseException at the end of the day to throw them)
Paul Betts
+8  A: 

Poor implementations of exception handlers push some kind of exception handler block for each try clause on the runtime stack as the try clause is entered, and pop it off as the try clause is exited. A location holding the address of the most recently pushed exception handler block is also maintained. Typically these exception handlers are chained together so they can be found by following links from the most recent to older versions. When an exception occurs, a pointer to the last-pushed EH handler block is found, and processing of that "try" clause's EH cases is checked. A hit on an EH case causes stack cleanup to occur back to the point of pushed EH, and control transfers to the EH case. No hits on the EH causes the next EH to be found, and the process repeats. The Windows 32-bit SEH scheme is a version of this.

This is a poor implementation because the program pays a runtime price for each try clause (push then pop) even when no exception occurs.

Good implementations simply record a table of ranges where try clauses occur. This means there's zero overhead to enter/exit a try clause. (My PARLANSE parallell programming langauge uses this technique). An exception looks up the PC of the exception point in the table, and passes control to the EH selected by the table. The EH code resets the stack as appropriate. Fast and pretty. I think the Windows 64 bit EH is of this type, but I haven't looked carefully.

Ira Baxter
+2  A: 

The C++ standard committee published a technical report on "C++ performance" to debunk many myths about how C++ features supposedly slow you down. This also includes details about how exception handling could be implemented. The draft of this technical report is available for free. Check section 5.4.1. "Exception Handling Implementation Issues and Techniques".

sellibitze