[vox-tech] Where setjmp/longjmp went after C
Haiying Wu
vox-tech@lists.lugod.org
Wed, 4 Sep 2002 02:13:13 -0700 (PDT)
"[vox-tech] Where setjmp/longjmp went after C" is a
good article. But I have to point out a possible
mistake.
I think there are risks to define macro"#define
JB_ENDTRY }JB_ULN}".
for example, in code:
void b( char volatile c )
{
int caught=0;
printf( "entered b with c=%c\n", c );
JB_TRY( &caught ) {
printf( "doing f\n" );
f( c );
printf( "did f\n" );
g( c );
printf( "did g\n" );
} JB_CATCH( EXCEP_MATHERR ) {
printf( "caught MATHERR exception in b\n" );
JB_RAISE( EXCEP_INVALIDARGS );
} JB_CATCHDEFAULT {
printf( "caught some other exception... c=%c,
caught=%d\n", c, caught );
JB_RAISE( caught );
} JB_ENDTRY;
printf( "leaving b\n" );
}
It's OK. But what if there is no another exception
raised in catch block or catch-default block? See the
following code:
JB_CATCH( EXCEP_MATHERR ) {
printf( "caught MATHERR exception in b\n" );
/*JB_RAISE( EXCEP_INVALIDARGS );*/ //no new
exception raised
}
then, JB_ENDTRY will be executed after JB_CATCH block
.
So, JB_ULN will be executed twice, it is dangerous!
A possible solution to this problem is to:
(1)#define JB_ENDTRY }}
(2)#define JB_NORMAL_TERMINATE JN_ULN
(3)add "JB_NORMAL_TERMINATE" at the end of normal code
(try block).
So the code becomes:
JB_TRY( &caught ) {
...
JB_NORMAL_TERMINATE;
} JB_CATCH( EXCEP_MATHERR ) {
...
} JB_CATCHDEFAULT {
...
} JB_ENDTRY;
Certainly, to eliminate the explicit statement
"JB_NORMAL_TERMINATE" in user code, we can define
macro JB_FIRST_CATCH:
#define JB_FIRST_CATCH JB_ULN;JB_CATCH
By user's explict code or by complier's implicit
translate, the final code would look like:
JB_TRY( &caught ) {
...
} JB_FIRST_CATCH( EXCEP_MATHERR ) {
...
} JB_CATCH( EXCEP_... ) {
...
} JB_CATCH( EXCEP_... ) {
...
} JB_CATCHDEFAULT {
...
} JB_ENDTRY;
__________________________________________________
Do You Yahoo!?
Yahoo! Finance - Get real-time stock quotes
http://finance.yahoo.com