cppannotations/annotations/yo/exceptions/jmp.yo

32 lines
1.9 KiB
Text

The basic program from the previous section is slightly modified to contain a
variable
hi(jmp_buf) tt(jmp_buf jmpBuf) used by ti(setjmp) and ti(longjmp).
The function tt(Inner::fun) calls tt(longjmp), simulating a disastrous
event, to be handled near tt(main)'s end. In tt(main) a target location for
the long jump is defined through the function tt(setjmp). tt(Setjmp)'s zero
return indicates the initialization of the tt(jmp_buf) variable, in which case
tt(Outer::fun) is called. This situation represents the `normal flow'.
The program's return value is zero em(only) if tt(Outer::fun) terminates
normally. The program, however, is designed in such a way that this won't
happen: tt(Inner::fun) calls tt(longjmp). As a result the execution flow
returns to the tt(setjmp) function. In this case it does em(not) return a zero
return value. Consequently, after calling tt(Inner::fun) from tt(Outer::fun)
tt(main)'s tt(if)-statement is entered and the program terminates with return
value 1. Try to follow these steps when studying the following program
source, which is a direct modification of the basic program given in section
ref(BASICEXCEPTION):
verbinclude(-a examples/jmp.cc)
This program's output clearly shows that tt(inner)'s destructor is not
called. This is a direct consequence of the non-local jump performed by
tt(longjmp). Processing proceeds immediately from the tt(longjmp) call inside
tt(Inner::fun) to tt(setjmp) in tt(main). There, its return value is unequal
zero, and the program terminates with return value 1. Because of the non-local
jump tt(Inner::~Inner) is never executed: upon return to tt(main)'s tt(setjmp)
the existing stack is simply broken down disregarding any destructors waiting
to be called.
This example illustrates that the destructors of objects can easily be skipped
when tt(longjmp) and tt(setjmp) are used and bf(C++) programs should therefore
avoid those functions like the plague.