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 04:34:06AM +0100, Gabriel Dos Reis wrote:
> | 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.
>
> I'm not sure that extra linguistic facility is really in accordance
> with C++ rules (I'm not sure 12.8/15 applies here).
I couldn't think of a clearer way to express the necessary effect.
Each longjmp (throw) needs to transfer control to one specific setjmp
(catch block); leveraging the uniqueness of objects seemed like the
obvious way to do it. Unfortunately, jmp_buf objects are passed
around by value, so I couldn't see any way to avoid some sort of
internal hack.
> Furthermore after call to calls_longjmp(), the object env ceases
> existing -- it isn't even visible in the catch block so I assume you
> wanted
>
> jmp_buf env;
> try {
> env.setjmp_return_value = 0;
> // ...
Yes. Oops. You can tell I've done more Python than C++, eh?
That's actually good; we could then restructure it as
jmp_buf env;
env.setjmp_return_value = 0;
for (;;) {
try {
...
break;
} catch (jmp_buf E) {
if (E is env)
continue;
throw;
}
}
and avoid the dubious goto. Read "E is env" as whatever has to be
done to check the identity constraint.
> | I claim that any use of setjmp/longjmp that won't work with this
> | implementation is already invoking undefined behavior.
>
> Well, let's first address the case of situations that "work" with the
> above scheme before addressing the validity of the claim. What is
> supposed to happen for the rethrow case?
If control reaches "throw;" you mean? That happens when the jmp_buf
that was jumped to, isn't the jmp_buf that was initialized in this
stack frame, so we should keep unwinding. Presumably, higher up the
stack, there is a jmp_buf that we do want to jump to. If not, do
whatever is normally done for an unhandled exception (call
std::terminate, isn't it? Come to think, if we're doing exceptions in
C, we need a C equivalent of that...)
zw