l i n u x - u s e r s - g r o u p - o f - d a v i s
L U G O D
 
Next Meeting:
August 5: Social gathering
Next Installfest:
TBD
Latest News:
Jul. 4: July, August and September: Security, Photography and Programming for Kids
Page last updated:
2002 Sep 05 15:16

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] Where setjmp/longjmp went after C
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] Where setjmp/longjmp went after C



On Wed, 4 Sep 2002, Haiying Wu wrote:

> "[vox-tech] Where setjmp/longjmp went after C" is a
> good article. But I have to point out a possible
> mistake.

Exceptions are indeed tough to implement in a fashion that always seems
"right".  Including them in the C++ language allowed this error-prone code
problem to be handled by the compiler so the programmer would have fewer
opportunities to screw it up.

> I think there are risks to define macro"#define 
> JB_ENDTRY  }JB_ULN}".

It does _look_ risky, but it isn't. :)

> 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!

It would be, except that the implementation of JB_ULN is simply to
overwrite the "head" pointer to the list with the "next" pointer from the
current context.  Overwriting a pointer with the same value twice doesn't
actually cause any ill effects.

The code

  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;

preprocesses to

  {jbnode
jbnode_local;jbnode_local.next=jbnode_head;jbnode_head=&jbnode_local; ;switc
h((*(  &caught  ))= _setjmp ( jbnode_head->this ) ){case 0:  {
    printf( "doing f\n" );
    f( c );
    printf( "did f\n" );
    g( c );
    printf( "did g\n" ); 
} break;case ( 1 ): jbnode_head=jbnode_local.next; ;  {
    printf( "caught MATHERR exception in b\n" );
     
  } break;default: jbnode_head=jbnode_local.next; ;  {
    printf( "caught some other exception... c=%c, caught=%d\n", c, caught
);
    longjmp(jbnode_head->this,(  caught  )); ;
  } }jbnode_head=jbnode_local.next; } ;

where the execution path through the default catch shows why the JB_ULN
needs to be in JB_CATCHDEFAULT (JB_RAISE needs to operate in the next
higher context), and the non-exception TRY path shows why it has to be in
JB_ENDTRY (if there were no exceptions, the context would have to be reset
at the end of the select statement).

> 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).

I think I have explained why this is not necessary... there is no problem
invoking JB_ULN twice.  My offered syntax is more compact and easier to
remember when coding than the alternatives you offered.  It is still not
signal() safe though, so ideas on how to make it so would be welcome.

Thank you for your comments... an example of GooglePower!

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil@dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live Go...
                                      Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...2k
---------------------------------------------------------------------------

_______________________________________________
vox-tech mailing list
vox-tech@lists.lugod.org
http://lists.lugod.org/mailman/listinfo/vox-tech



LinkedIn
LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
facebook
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
O'Reilly and Associates
For numerous book donations.