/* we use a special form of short circuit evaluation here, since \
setjmp is only allowed in restricted contexts */ \
switch (!!p00_unwind_bottom) \
case 1: \
/* If an unwind is possible, i.e if we are not in the outer frame \
this will stop the evaluation of the expression here, and unwind \
as side effect. Otherwise, this will continue normally and \
directly proceed with the return. */ \
if (!setjmp(p00_unwind_bottom[0]->p00_buf)) { \
/* assign before we unwind all the way down */ \
p00_unwind_bottom[0]->p00_returning = 1; \
P99_UNWIND(-p99_unwind_return); \
} else case 0: P99_ALLOW(RETURN) return
#define P99_ALLOW(NAME)
Allow the use of feature NAME inside the dependent code.
Definition: p99_block.h:150

Return from the enclosing function after unwinding all levels of nested P99_UNWIND_PROTECT.

By this you can guarantee that all eventually existing P99_PROTECT parts of enclosing P99_UNWIND_PROTECT are properly executed. This is in some way similar to the guarantee of C++ to call destructors before returning from a function.

There is one important difference, though: the return expression (if any) is evaluated after the protected parts are unwound. So if these modify parts of that return expression you might not get what you expect. So instead of

You might want do something like

volatile retType myret = expr;
Utilities that change control flow in an unexpected way may result in the loss of some modifications that are effected on variables. A modern compiler should tell you when you are in such a situation. If it is the case you'd have to declare the variable in question with the volatile qualifier. For an explanation see P99_UNWIND_PROTECT.

Definition at line 714 of file p99_block.h.