This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [basic-improvements] try/finally support for c/c++ - more tests
On Thu, Nov 07, 2002 at 03:14:25AM +0100, Gabriel Dos Reis wrote:
> Zack Weinberg <zack@codesourcery.com> writes:
>
> | p.s. It would be nifty if setjmp/longjmp could be defined in terms of
> | exception handling. Anyone put thought into that?
>
> EH in C++ sense essentially makes control flow flows one direction
> whereas setjmp/longjmp transfers control virtually anywhere.
Imagine a setup like this:
class jmp_buf {
int setjmp_return_value;
} __attribute__ ((always_passed_by_reference));
void calls_longjmp(jmp_buf env)
{
env.setjmp_return_value = 1;
throw env;
}
void calls_setjmp(void)
{
try {
jmp_buf env;
env.setjmp_return_value = 0;
control_transfers_here_twice:
if (env.setjmp_return_value == 0) {
puts("first call to setjmp()");
calls_longjmp(env);
} else {
puts("second call to setjmp()");
}
} catch (jmp_buf E) {
if (&E != &env)
throw;
goto control_transfers_here_twice;
}
}
The "always_passed_by_reference" bit ensures that when control
transfers to the catch clause, &E == &env if and only if it was
'env' that got longjmped to.
This is not possible to achieve with macros, of course -- imagine this
as a compact representation of the tree structure generated when
__builtin_setjmp and __builtin_longjmp are used. (Which builtins
should not be confused with the existing ones of the same names.)
I claim that any use of setjmp/longjmp that won't work with this
implementation is already invoking undefined behavior.
Code that calls longjmp from a signal handler would have to be
compiled with -fasynchronous-exceptions, and we wouldn't want to do
this on a platform that couldn't unwind through a signal handler
frame.
(I'm assuming it is okay to perform that goto. I think such is the
case, but I could be wrong.)
zw