Re: confused by exception handling in VC 2008

Tech-Archive recommends: Fix windows errors by optimizing your registry



See below...
On Mon, 8 Dec 2008 11:28:21 -0800 (PST), max <maxxx126@xxxxxxxxx> wrote:

I am using VC 2008 and I was trying the __try exception handling and I
bumped into the following 3 cases:

1)
__try {
char *p = 0;
*p = '\0';
AfxMessageBox("no exception caught");
}
__except (EXCEPTION_EXECUTE_HANDLER){
AfxMessageBox("exception caught");
}

the message "exception caught" is displayed as expected.
****
Be aware that Structured Exception Handling (SEH) and C++ Do Not Play Well Together.
Therefore, you should never use __try/__except in a C++ program
****

2)
__try {
int v[5];

v[10] = 1; // This vector access is out of range
AfxMessageBox("no exception");
}
__except (EXCEPTION_EXECUTE_HANDLER){
AfxMessageBox("exception caught");
}

no exception raised, the message "no exception" is displayed !
****
Sure. Why would you expect it to raise an exception? There's absolutely NOTHING here
that would remotely suggest that an exception should be raised. Of course, the fact that
you are using and int[5] array and using an out-of-range index suggests that you really
don't understand modern programming. Fixed-size C-style arrays should be considred
extremely rare and exotic situations, and you must write your code in such a way that the
error you have illustrated above CANNOT HAPPEN because THERE IS NO WAY TO DETECT IT!

So the example represents sloppy programming.
****

3)
__try {
char *p = 0;
int v[5];

v[10] = 1; // This vector access is out of range
*p = '\0';
AfxMessageBox("no exception");
}
__except (EXCEPTION_EXECUTE_HANDLER){
AfxMessageBox("exception caught");
}

In this case the application crashes, the exception handler failed.
****
You used the sloppy word "crash" and did not explain what it meant. This is a nonsense
term, and when you use it without saying IN PRECISE DETAIL what the external manifestation
of the error condition was, you are merely generating noise without any content. If you
want to ask a question about some kind of abnormal termination, you will have to give
EXACT DETAILS, including the stack backtrace, and in general, the values of all the
variables involved along the way.

So the answer to (3) is the same as (2): you wrote an erroneous program for which THERE IS
NO POSSIBLE REASON TO SUSPECT THAT YOU WOULD SEE AN EXCEPTION, and the programs simply
misbehave in some unexpected fashion. The general response is "tough". You wrote bad
code. It fails. Do not expect any kind of meaningful response by the C environment, and
certainly there is absolutely no reason to expect an exception.

I suspect that your bad assignment clobbered the exception frame and therefore the
exception handler could not execute. This then manifested itself as some other error that
you gave no details about.

Why do you even THINK that an out-of-range subscript as shown is going to do anything
meaningful? Even the language defines it has merely producing unknown and unknowable
damage to the contents of memory.
*****

Any ideas for the behaviour of cases 2) and 3) ?
****
First rule: DO NOT USE SEH WITH C++. It doesn't work. Any appearance of working is
merely an accident.

Second rule: DO NOT USE RAW C ARRAYS TO STORE DATA unless you MAKE SURE that you cannot
possibly have an out-of-range subscript. This is because out-of-range subscripts are
defined by the language to simply be erroneous code that produces unknown and
unpredictable effects.

Third rule: DO NOT USE RAW C ARRAYS TO STORE DATA except in EXTREMELY RARE AND EXOTIC
SITUATIONS.

If you are using MFC, you can use the CArray type and its various flavors, such as
CStringArray, CByteArray, etc., but in general you will want to learn the Standard C++
Library collections, such as std::vector, which are cleaner.

Your examples are poor examples. They use mechanisms incompatible with C++, try to
execute programs whose semantics are undefined, and no matter WHAT they do, it is an
accident. Their behavior is completely undefined, unknowable, and unpredictable.

If you use out-of-range subscripts on MFC arrays or std::vector, they WILL throw an
exception (actually, MFC collections will take ASSERT failures in debug mode, so you can
find out why your program is screwed up), because these collections are DEFINED to throw
exceptions (although there are situations such as having the exceptions disabled in the
collections for the release build to improve performance). C is not Java. Don't expect
it is going to work like Java. It is going to work like C, which is to say, there are no
bounds checks on arrays, and the effects of storing out-of-bounds is merely "undefined".
Usually, it just does some kind of damage which shows up later as something else
malfunctioning.

Storing through a NULL pointer and getting an exception is just an accident of the
implementation of the operating system, which is specially configured to trap any attempt
to access an address in the range 0x00000000-0x0000FFFF. There's actually nothing in the
C language that requires that an exception be thrown; the language specifically says that
assigning through a NULL pointer (why are you assigning 0 to a pointer instead of NULL, by
the way?) is simply *undefined behavior*. So it is the merest accident that in Windows
such an assignment just *happens* to have the side effect of causing a memory access
failure. The program is merely incorrect, and is not expected to work properly, or in any
definable or predictable fashion. It is erroneous design to expect otherwise.
joe

Max
Joseph M. Newcomer [MVP]
email: newcomer@xxxxxxxxxxxx
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
.



Relevant Pages

  • Re: initial lang spec: SXIL...
    ... Shouldn't some of that functionality be moved into the exception ... but, of course, natively using SEH requires compiler support. ... throws a fixed exception code in my case, and generic handlers are used. ... It took many years, and a language review, before I realized that my fond ...
    (comp.lang.misc)
  • Re: c++ documentation
    ... Alternatives to understanding how the language maps onto the metal? ... One can do a lot with C++ without ever using a raw pointer directly if one ... Code that is not exception safe impedes this. ... I do agree that some programmers overuse the ...
    (comp.os.linux.development.apps)
  • Re: Porting ILE C to GNU C - #pragma cancel_handler
    ... code to Linux as GNU C. ... In the former case, you aren't able to catch that - neither in UNIX, nor ... even any) exception handling mechanisms in .NET, ... programming language in Linux. ...
    (comp.sys.ibm.as400.misc)
  • Re: Structured exception information
    ... Tcl is a powerful language that is quite successful ... I said "Strings are the correct type for presenting information to the ... And yes, Ada exceptions ... But I don't understand _why_ you want to do that in the exception ...
    (comp.lang.ada)
  • Re: finite state machine
    ... language, ... tail recursion at the abstract machine level, due to destructors being invoked and exceptions being checked against exception specification list. ... Java lacks automatic destructor invocation on leaving scopes, but in that language exception checking is commonly used. ... Exception checking by itself still leaves room for optimization if the tail-recursive call is a call to the same routine, or if the routine called has the same exception specification. ...
    (comp.programming)