Handles situations when a destructor of an object throws an exception during the stack unwinding (more about this later).

Allowes to process exceptions before the stack unwinding (both C++ and SEH).

Allowes to cancel exceptions (SEH).

This implementation is suited for the Msvc (MS Visual C++) compiler. But with some efforts it may be ported to other OS and compilers. Depending on the compiler/platform there may be no need to optimize the performance. However ability to handle gracefully exceptions thrown from d'tors (destructors) and to do things "during" the exception handling before the exception is actually caught and the stack is unwound - is a great feature. And it's unfortunately missing in the native C++.

I have to mention this article: How a C++ compiler implements exception handling. It describes in-depth how the compiler implements exception handling, plus it contains a custom implementation of it. Actually some time ago it helped me to solve problems with exception handling in device driver development. However the implementation provided in that article is pretty heavy, uses a lot of STL, and could not be used as-is in the device driver code. Hence - I've made my simplified implementation of exception handling, which supported only the part that was necessary for me. Later I've completed that implementation, so that it remains lite and minimalistic, yet complete and powerful.

This article also contains some theoretical background about the exception handling and its implementation, which is necessary to understand how exactly this customized imeplementation is designed and what's so special about it.

Exception handling

Surprisingly exception handling is one of the most mystified subjects in programming overall and in C++ specifically. And it's very important to know how it works and what are its benefits and limitations.

I recommend reading the article I've mentioned at the beginning. Also I recommend reading the following article: Drivers, Exceptions and C++. It observes relation between C++ exception handling and SEH, as well as effects of setting exception handling models for compiler (synchronous, asynchronous, etc.).

Here are the key things that must be clear before we continue:

There're different exception handling models. All they consist of the following steps:

Interruption of the normal program flow and passing control (with some parameters) to the exception handling mechanism.

Search for the appropriate catch block. More precisely - negotiation with exception handling blocks until one decides to handle it.

Stack unwinding procedure up to catching block. During this stage every exception handling block may execute its cleanup code.

For every automatic (on stack) object with d'tor the compiler automatically generates exception record, similar to __try/__finally block.

For try/catch blocks compiler automatically generates exception record, similar to __try/__except block. However it conceals the "negotiation" with exception handling mechanism. Instead it automatically decides to handle or not the exception based on the C++ type match.

In this example the compiler will generate so-called frame handlers in both functions. In SomeFunc its purpose is to call the d'tor of obj1 if the exception escapes the function. So that during the "negotiation" stage it does nothing (refuses to catch the exception). And during the unwind phase it calls the d'tor of obj1.

The frame handler generated for AnotherFunc has more things to do. During the negotiation it checks the exception parameters. If it comes out to be a C++ exception with C++ type matching the caught one (int) - it handles the exception. The handling means several things:

Unwinding the stack. During this procedure the frame handler of SomeFunc gets called to destroy obj1

So-called "local" unwind. Means - objects that reside within the appropriate try block should be destroyed. In our case obj3 is destroyed. Other objects within AnotherFunc remain alive

Assigning the thrown value to the appropriate variable of the catch statement

Calling the catch block

After the catch block returns - passing control right beyond it.

And if the exception is not caught - it propagates until another block decides to catch it. Then it'll call the frame handler of AnotherFunc to destroy its objects that are currently alive. In our case those are obj3 and obj2.

Now let's see in details the exception handling mechanism at work:

For throw statement the compiler generates a call to _CxxThrowException CRT function. It gets two parameters: pointer to the thrown object and a pointer to some data structure that fully describes its type information.

_CxxThrowException calls RaiseException API function with exception code and parameters such that the appropriate catch blocks recorgnizes it to be a C++ exception and its thrown type and value.

RaiseException function performs a kernel-mode transaction (sort of an interrupt). That's how the OS gets notified about the exception.

If there's a debugger attached to the process - it gets notified about the exception.

The OS checks if this exception needs its intervention. Some exceptions (such as page fault) are handled internally by the OS and the application continues execution as if nothing happened. That is, the first exception handler is actually the OS.

Obviously the OS has nothing to do with C++ exceptions. Hence it just passes control to the user-mode exception handling mechanism.

The user-mode mechanism analyzes the chain of registered exception registration records. It invokes the frame handler of every such a record until one decides to handle the exception. This is the negotiation stage.

The handler that decided to handle the exception performs what we already discussed: stack unwind, its local unwind, call of the catch block (with some preparations), and finally passes control right after the catch block.

Customizations

As we've seen there're several components involved in exception handling. All of them may be customized (replaced). What's important is that they are all independent and the customized implementations are compatible with the standard ones (more about this later). That is, you may customize only the components you want, to achieve the needed effect. Now let's discuss them and how they're implemented

Replacement for RaiseException

The RaiseException function is very heavy. Because it involves a kernel-mode transaction (goes into the OS internals). The cost of calling a kernel-mode function is several thousands of CPU cycles, even if that function does nothing. For comparison: calling a regular function takes just a few cycles on a modern CPU. And things get much worse when there's a debugger attached to the process: the OS immediately suspends our process and notifies the debugger that we got an exception. The debugger responds, emits the annoying "First-chance" blabla and then releases our process. The performance degradation is so catastrophic that in many situations it's simply impossible to debug programs.

Exception handling is often criticized for being heavy and slow. But this is actually a question of implementation. Let's thing again: is there a real reason for a kernel-mode transaction for exception handling? There're two official reasons:

Make the OS (and debugger) aware of the exception.

But this does more harm than good IMHO. I don't see why the debugger should be aware of every exception in the program. There's a lot of situations where exceptions are something absolutely normal, that doesn't require any attention.

Give the OS an opportunity to handle it.

This is even more ridiculous. The OS has nothing to do with software application-level exceptions. Especially it has obviously nothing to do with C++ exceptions.

Hence I decided to implement a user-mode variant of RaiseException. That's how it's declared:

Replacement for _CxxThrowException

The next logical step is to use the Exc::RaiseExc for C++ exceptions. As we've already seen C++ exceptions are thrown via the _CxxThrowException function that is implemented in CRT. Now we'll make it throw exception via our function. This is enabled/disabled by the following:

namespace Exc
{
void SetThrowFunction(bool bSet);
} // namespace Exc

This function enables/disables at runtime our replacement for the _CxxThrowException. This is achieved by overwriting the first portion of the function body by a jmp instruction into our function. Theoretically it's possible to build the program statically linked to our function instead of the standard _CxxThrowException, but this method requires a lot of linker adjustments. Plus this can create a mess when used across EXE/DLL boundarios (more about this later).

Pros:

Much better performance for C++ exceptions.

Replacement for frame handlers

Frame handler is a function that gets called for every function that needs exception handling. It's implemented in CRT and is called _CxxFrameHandler3. Among other parameters it receives a so-called frame information, which contains all the information about its try/catch blocks and the objects with d'tors.

One of the known problems of C++ is exception thrown from within a d'tor during the exception handling. But there're actually more problems with this. If you throw a C++ object (rather than a simple ordinaty type) - the exception handling mechanism creates a copy of this object via its copy-c'tor, and at the end of the process the d'tor of this temporary object is called as well. Moreover, if you catch such an object in the catch statement by value rather than reference - another copy-c'tor is called. And all those steps (including d'tors during unwinding) must be error-free. If any of the above throws an exception - the CRT implementation of the frame handler immediately calls terminate function, and the game is over.

Worth to note here that this problem is C++ - specific. In SEH there's absolutely no problem if during exception handling another exception is raised. In such a case the new exception is handled recursively by the same mechanism. Moreover, in SEH every exception handler sees the chain of all the exceptions raised yet not handled so far. This is called nested exceptions.

In C++ however there seems to de a design problem with this. It originates to the fact IMHO that exception handling in C++ is too much concealed. You just throw an exception and ... oops! You've already caught it! And yes, the d'tors of your objects are already called. But wait, if d'tors are called - this means that my program is actually working. And, like every piece of code, it has some reasonable opportunity of failure.

Well, it's argued that d'tors must never fail. This makes sense: d'tors are often used to perform sorts of a cleanup. And if you have a cleanup problem - this problem is actually non-recoberable. That is, it's legitime if you can't open a file for example, but if you can't close a valid file handle - there is a much deeper problem in the API. But on the other hand d'tors are not always used for cleanup only. Here we obviously have a problem. Also, as we've already said, there's also a problem with copy c'tors during exception handling, which have a legitime opportunity of failure.

Nevertheless, I've created another implementation of the frame handler that handles this situation. If an exception is raised during the exception handling (in either d'tor or copy c'tor) - exception handling mechanism is activated recursively. At this stage the new exception "joins" the list of currently-being-handled exceptions, and we proceed with respect to all the exceptions, until they're all handled.

Now, here there's some degree of freedom about the order in which exceptions should be handled. Previous (1st-generation) version handled exceptions in the LIFO (last in first out) order. In simple words - recursively. The drawback of that approach was that it could allow exceptions excape their target catch blocks, where they were preceeded by those exceptions that had to be handled in outer catch blocks. Let's look at the following example:

Here catch block for B preceeds that for A. At runtime B is thrown. But then before it's caught A is thrown as well. In this case the 1st-generation implementation would handle A first, which unwinds the stack up to the catch block of A. Then we return to handling B, but it's now unstoppable.

The question is what should be the correct behavior in such a case. Is it ok to "swap" the order of exceptions to prevent their escaping? I took some time thinking about this, and my conclusion was that this is indeed the correct thing to do. You may think of an exception as a way of abortion of some portion of the code, which ends exactly at the appropriate catch block. If you have several error conditions simultaneously each of which demands abortion up to some point - obviously you should not abort beyond the most outer of them.

Finally I've decided to rewrite the nested exception hanlind behavior, which led to the 2nd-generation exception handling mechanism. When nested exceptions occur they're handled such that every catch block attempts to catch any of the active exception. Moreover, if the same catch block can catch several exceptions - that's what it will do, and the code within it will be invoked several times. In conclusion the policy regarding the nested exceptions is the following:

Every catch block may catch any of the currently active exceptions.

The same catch block may catch more than one exception.

catch block may be called more than once.

After the catch block is invoked the control is not guaranteed to be passed right after it.

All the d'tors are always called once.

Exception handling proceeds until all the exceptions are handled. At the end the control is passed after the last (most outer) catch block.

If an exception can't be handled UnhandledExceptionFilter is called.

Usually you may assume that every your catch block is called no more than once. Also you may assume that after the catch block is executed you definitly get control after it. But if nested exceptions occur this rule may break. So that my customized frame handler gives you an opportunity to handle nested exceptions gracefully, but it's your duty to make sure this is indeed so.

To replace the standard CRT frame handler the following function should be called:

namespace Exc
{
void SetFrameHandler(bool bSet);
} // namespace Exc

This function enables/disables at runtime our replacement for _CxxFrameHandler3. This is achieved by the same method we've already used: overwriting the first portion of the function body by a jmp instruction into our function.

Pros:

Handles situations with exception during the exception handling.

Significantly faster than the standard imeplementation.

Exception monitoring

One of the features available in SEH but still missing in our implementation is ability to do explicit processing of the exception during the negotiation stage, and optionally cancel it. Note: you actually get an opportunity to do things before the unwinding even begins. Hence the whole stack is still valid, and it contains valuable context information. This is extremely valuable for debugging, error/crash handling, and even for logging. For more information about this I recommend reading this article: Superior logging design. Fast but comprehensive.

This functionality can be achieved easily by using pure SEH. You may wrap some code block by __try/__except block and you'll have an opportunity to analyze exceptions (and possibly do some extra processing) within the __except statement. But here comes another problem: it comes out that you can't use SEH blocks in any function that has its automatically-generated exception handling records. Means - any function that has either a try/catch block or an object with d'tor. One of the ways to overcome this is to split your function into several ones, so that we won't mix SEH and C++ exception handling in one function. This however is pretty annoying. To make life easier I've decided to give a C++ - -wrapped possibility to achieve this. Let's look at the following class declarartion:

Override the Handle function in an inherited class, and you'll get called during the negotiation. If you return true - means you've handled the exception and the execution should continue from the point where the exception has been raised (equivalent to EXCEPTION_CONTINUE_EXECUTION in SEH). You may also override AbnormalExit to get notified when the scope is exited upon exception. (In contrast regular d'tor called in both normal and abnormal scope exit). You must however obey the following rules with using this technics:

Always create this object on stack only (declare as an automatic variable). Never create this object dynamically (via new operator or something similar). Also don't do any sophisticated adjustments to its lifetime. If you break this rule - exception registration record chain may get corrupted, and the program will crash.

Don't try to cancel exceptions that have the EXCEPTION_NONCONTINUABLE flag on.

In particular C++ exceptions are always non-continuable, and you should not try to make them continuable. This is because the compiler assumes the execution may never continue beyond the throw statement, and it may not generate valid code after it.

Actually I had another idea about exception monitoring in a C++ way - without using __try/__except directly. I thought about invoking the code inside the catch block before the stack unwinding for some specific thrown types. I declared some abstract class, and every exception of this type (and any C++ class derived from it) is actually caught before the stack unwinding. By such you could use exceptions of those types to be able to do more inside the catch block. For instance:

Unfortunately this perverted trick has failed for reasons independent of me. It worked well in debug, but crashed in release build. It came out the compiler assumes that inside the catch block all the objects instantiated within the try block are already dead, and their memory may be reused. Hence for objects declared within the catch block it generated code that overwrites the memory of those declared in the try block. I had even more fanatic ideas with creating a copy of the stack memory of the appropriate try block before invoking the appripriate catch, but then there would be problems if the catch block rethrows an exception, and so on. At the end, with heavy heart, I gave up. And then I've created the Monitor class that does the trick.

Constraints

The first concern is with using our exception handling accross EXE/DLL boundaries. There's no problem if you use DLL version of CRT (in all your DLLs and the EXE), and the global initialization of our exception handling resides in the EXE only, so that all other DLLs have no direct connection to the customized exception handling. In this case we replace the CRT version of exception handling, and all the modules automatically use it. If however some modules use statically-linked CRT libraries - their exception handling will remain intact.

Another conern is related to the fact that our implementation uses TLS (per-thread variables) to keep some information about currently being processed exception. This is necessary to correctly implement "rethrow" (throw; statement) and nested exception handling. The problem is that CRT implementation also has this sort of a per-thread exception handling information (though without support for nested exceptions), which is not related to ours. Moreover, when CRT is used as a DLL this information is inaccessible to the EXE (internal CRT functions that access it are not exported). When we handle an exception the CRT isn't aware of that, and vice versa. This has two implications.

One of the implications of this is that std::uncaught_exception() will not see exception that we handle. To overcome this I've added the following functions:

namespace Exc
{
// Replaces std::uncaught_exception
void SetUncaughtExc(bool bSet);
// Returns the currently processed exception
// In contrast to std::uncaught_exception this function not only tells if
// there's currently exception being processed, but also what it is
EXCEPTION_RECORD* GetCurrentExc();
} // namespace Exc

There's also one more little problem that can arise in very special conditions. If there's a C++ exception raised by our mechanism, during which an implicit SEH exception occurs (such as access violation) - the new exception is not immediately "chained" to the previous one, so that at the beginning it doesn't contain the nested exception information. In such a case when our frame handler is being invoked for the first time - it sees that the new exception is not chained yet, and immediately chains it, so that there's no problem for all the consequent handlers. If however the first exception handler happens to be the SEH one (with __try/__except block) - it won't see the nested exception at the beginning. That is:

Well, this problem is very specific IMHO. Anyway nested exceptions are unfortunately ignored often, the even fact we take them into account is something unusual. To solve this problem either don't use SEH exception blocks directly at least where you raise exceptions via our mechanism (the whole idea is to get rid of using SEH directly), or when analyzing the exception you may also call Exc::GetCurrentExc to see if there're currently more exceptions being processed. Theoretically it's possible to replace the CRT code that support the SEH exception blocks (_except_handler4), but this is too much effort IMHO for something too unusual.

Another problem is that my exception handling mechanism currently doesn't support so-called vectored exception handling. It's an extension to SEH introduced in Windows XP. In addition to SEH it allowes to register global scope-independent handlers that automatically see every exception. The reason I didn't implement support for this is that I haven't discovered yet how to retrieve the table of all the registered vector handlers (there's no official API that does this). Plus this is something very specific, I doubt if it's actually used besides some very special conditions. So that I think there's no problem with this. And if however you insist on keeping vectored exception handlers - you should use the native RaiseException function rather than our fast Exc::RaiseExc. And if you want them to work for C++ exceptions as well (although I don't see any reason for this) - don't replace the _CxxThrowException.

Conclusion

C++ is often criticized, but I believe it's a great programming language after all. If you ask me what are the major differences between C and C++ I'd say the following:

The first category consists of many things that make writing code in C++ easier, however they don't bring anything new on the machine level. They just allow to achieve the same effect you'd have in C, with much shorter and cleaner code. The second category makes the compiler generate code to support polymorphism automatically, however C programmers could use polymorphism too: in old good times C programmers manually constructed tables of pointers to functions to achieve the needed effect at runtime. The remaining two categories: destructors and exceptions. And those are IMHO the greatest features of C++ compared to C. And, as we've seen, they're not actually two distnict features, there's a very tight connection between them.

Some criticize C++ for things that it doesn't do. Such as no reflections, lack of built-in complex types, and so on. But I believe such a criticism is not justified. C++ grew up from C, which is the most minimalistic assembler-independent programming language. And what makes C++ so great is that it offers much more than C, without compromising the minimalism and efficiency of plain C, when used correctly. On the other hand I would criticize C++ for some things that it does, when it does them wrong way. And exception handling is unfortunately a perfect example of this. IMHO it's not designed well, the even fact it defines exceptions thrown is some situations as undefined behavior in which the program should be terminated immediately - is a shame. Plus it's implemented barbarically in CRT for Msvc.

Our customized exception handling fixes those imperfections. Now we have a well designed handling of all the exceptions in all possible situations. Plus we fix the ridiculous performance issue. Exception handling is no more that heavy. From my experiments in the simplest exception handling scenario like this:

try {
throw1;
} catch (int) {
}

The complexity of the exception handling here is comparable with several calls of strlen("Hello, World"). For comparison it's much lighter than heap operations (malloc and free).

One point that is still missing is a language-integrated ability to analyze exceptions during the negotiation stage. My attempt to call catch blocks before the stack unwinding has failed, so the only thing left is either to use the Exc::Monitor helper class for this, or just use plain SEH. There seems to be no better solution within the standard C++ limitations.

The implementation of the exception handling is about 900 code lines, which is not that much. There're some non-trivial things there. They can be classified into the following categories:

Need to deal with SEH and built-in C++ types, such as type information of the object thrown and catch blocks, frame info and etc.

Some code written in assembler.

Non-trivial program flow. Some functions instead of a conditional return pass control to other code blocks.

This also includes the fact that during exception handling new exceptions may occur, plus CRT-based exception handlers may be involved. Actually in order to guarantee correct behavior in all those situations additional exception handlers are used internally during the exception handling.

Nevertheless the code is somewhat readable IMHO, and with some efforts it can be customized further.

Share

About the Author

My name is Vladislav Gelfer, I was born in Kiev (former Soviet Union), since 1993 I live in Israel.
In programming I'm interested mostly in low-level, OOP design, DSP and multimedia.
Besides of the programming I like physics, math, digital photography.

Thank you (admittedly belatedly - I've been away from the site for a 15 months) for an thought provoking article.

It's interesting to see that using SEH for C++ exceptions was probably the wrong one. The implementers could have easily done it in without trapping to the kernel. If you have to have a code based exception handler you might as well keep the overhead down!

I probably won't use your code as I only use exceptions for critical errors that you can't recover from so it doesn't matter how long it takes. However the pleasure of the article for me is increased understanding and that's always good.

First. SEH is a hardware exception initiated by CPU primitively abstracted by OS to support intel, alpha, mips cpus. C++ exception initiated in software. Two has nothing in common.

Second. Destructors must not throw exceptions ever! Read "Effective C++" by Scott Mayers. Reason is that destructor is very likely to be called during stack unwinding resulting from an exception being thrown. If the destructor itself throws an exception, having been called as the result of an exception being thrown thet net result application is terminated. Not quiet the purpose C++ exceptions designed for.

1. I'm afraid you are wrong. Neither CPU nor other hardware components may initiate a SEH (or whatever) exception. They may cause interrupts, but exception is something managed purely in software.

Windows performs the translation of hardware interrupts into SEH exceptions, which may be handled by software (in either kernel or user modes).

In simple words: The CPU causes an interrupt (such as an invalid memory access), appropriate interrupt handler is invoked, the handler allocates an EXCEPTION_INFORMATION structure, fills it with respect to the interrupt parameters, and performs the exception handling (which includes analyzing the registered exception handler chain and calling the appropriate handlers).

However the exception handling chain may be triggered without the explicit hardware interrupt. A call to RaiseException does exactly this.

2. Well, exceptions and destructors is a complex matter, if we start discussing it here - we will not end this.
I do agree that avoiding exception in destructors is generally a good practice. However I also think that under specific circumstances exception in destructors are ok, at least from the conceptual perspective.
For instance in SEH there's no inherent problem with exceptions raised during stack unwinding. This is called "nested exceptions".

What I did in the article is an attempt to "legalize" the nested exception handling in C++. I am aware that this is not always appropriate, and sometimes may cause a bizarre behavior. But OTOH sometimes it may be useful IMHO.

Ok, I will give you more details, you can simulate this problem very easily: create a default VS2010 wizard generated win32 windows application and put the following declaration and another 2 executable lines that should be in somewhere like in the main():

Put a breakpoint at the VirtualProtect() call and then compile and run it in DEBUG build. When it breaks, press Alt+8 to open the disassembly, and then Step Over (F10) over each line. You will see that the last line of assembly code from the VirtualProtect() statement is a call to __RTC_CheckEsp routine, for me it gives a very strange crash when calling it. As said, I am running in a Windows Server 2008 R2 x64 machine, however I just tested in a Win7 x64 virtual machine and it also crashed.

Well, it is probably the way __RTC_CheckEsp function works, It might be throwing some kind of exception and so it will call __CxxFrameHandler3 which is not executable, and so on ...

Interesting thought. Still I don't think it's possible, but I need to check this. Unfortunately right now I have no way to test it on MSVC2010.

VirtualProtect is a Windows API function, exported by kernel32.dll. Even if it happens to throw a C++ (!!!) exception, it would probably handle it by the code within one of the system DLLs, OTOH __CxxFrameHandler3 is either statically linked into your EXE, or imported from the MSVC runtime library (msvcXXXX.dll).

In debug build a call to RTC_CheckEsp is put after every call of a function which is imported from any DLL. It checks if the value of the ESP register is corrupted after the function call. Usually this indicates inconsistent calling convention, function parameters or etc.

But I have no idea how this may depend on the parameters passed to VirtualProtect.

I suspect there is an antivirus at work. Viruses like to target exception handling routines, so antiviruses may do so as well.

Well, I'll check this when I have such a possibility. Thanks a lot for the details.

Hi !
Thanks for your article, it helped me to achieve some replacement of _CxxThrowException i was trying to achieve for logging purposes.
The FunctionHack was the thing I was looking for, but the entire article is really interesting also.

I write here to give a little insight about the VirtualProtext/RTC_CheckEsp issue.
I stumbled upon the same crash on debug builds and took the time to investigate.
I found that the _CxxThrowException code and RTC_CheckEsp appears to be on the same page of code (on my version of msvc anyway).
So setting, the page protection to only PAGE_READWRITE will throw an access violation exception when trying to execute RTC_CheckEsp.
And that is why setting it to PAGE_EXECUTE_READWRITE resolve the issue.

The world we're living in is just a particular "platform-dependent" implementation of what it could be theoretically. I suggest we don't concentrate on it too much.
Hence - I'll not take sincerely your vote, because it's also too universe/platform-dependent. I prefer to think about another world implementation, where you give me 5.

Yeah, if it was, why the __try, etc. __ means compiler specific code. Maybe in your small world where you only target Windows is a good thing. For me, it's more about allowing others from any world to use my code. That's my concern. So you can rate my comment with a 1 all you want. Because I know in reality, there is more than just one compiler to use.

Your comment was rated "1" by many people (4 so far), not only by me. I just think that your objection about platform-dependence is inapplicable, and probably many other readers agree with this.

BTW, the article tags are C++, Windows, Dev, Intermediate, Advanced.
If you looked for something platform-independent you could skip reading the article from the beginning.

If I could write the article + code in a platform-independent way without compromising relevant details - I would probably do so. But it's a matter of the subject. While concentrating on some technical details it's hard to remain platform-independent. Not to mention direct interfering with the assembler-level code and the OS. Obviously this lies outside the standard.
Yes, my implementation is very much platform-specific. Plus it's based on the particular exception handling strategy, which relies on SEH, which is also very much platform-specific.

So what?Should I apologize for this? I think not.

Don't like the platform dependence? Not using Windows? Fine, I don't insist. I didn't promise every reader that he/she will find this article extremely useful for the case.
I also don't give a damn about "political platform correctness". I just want to share my thoughts that some, but not necessarily all, - may find useful.

But this is not a legitimate reason for criticism. The criticism is welcome in case you find mistakes or disagree with some conclusions, or maybe the whole article idea looks wrong.

On the other hand you complain about don't-know-what. Did I fail your expectations and stolen your invaluable time? Or maybe you just got offended by the Windows "product placement" ?

But those are your problems. If I were you I'd simply skip the article, without posting ridiculous comments.

I guess, that you don't care about the average consumer wants. I wonder how you will make it in the programming world. I guess, if your boss told you to develop a Linux application. You would say no, simply, because you like using non-standard C++, and poor practises?

Oh right, because you probably couldn't understand how to use real api's. A lot of people on this site do write some good excellent code, but a lot of it, is really awful. But, as I said. If, you would use standard complaint code. I will change my vote. I could always go from 4 to a 1.

Being platform specific isn't a reason to rate the article 1. If you require cross-platform then simply don't use it. Doesn't mean its a bad article if the article is intended for a specific compiler/platform.

Hence you probably read the article inattentionally, because the difference between the "stupid extension" and the "defacto standard version" is explicitly described.

P.S.
Be so kind to watch your language. It's a technical forum, where people should teach and learn, share ideas or etc. Wanna blame me personally for stupidity - fine, I'm not going into discussion about this (I have more important things to do).

I have a question, though. Did you compare the performance only for x86 (32-bit) bulids? Exception handling on x64 is pretty different and you might get different results. Some details are available at a presentation given by Kevin Frei[^]

Yes, my implementation is x86/32-bit specific. And yes, I've compared the performance on x86 machines on Win32. To be exact: Intel Core Dual/Quad family processors, Windows XP and 2003, 32bit.

I've read the presentation that you suggested, which observes the difference in the implementation of EH between x86 and x64. They're related mainly to the overhead to the normal program flow due to the initialization of the exception records (which is much less on x64).

My implementation doesn't affect the normal program flow at all. I could not do this even if I wanted - the exception records are generated by the compiler, I can't interfere this.

In contrast my goal was (among other things) to optimize the performance when exceptions are raised. The main difference in the cost in this case is related to the fact whether or not kernel-mode calls are performed.

Yes, the presentation covers mostly the performance impact on the "normal" code flow. I should have probably posted a link to this MSDN topic[^]. It seems that EH on x64 is table-based, which probably results in differences in performance both in CPU and memory consumption compared to x86.