⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setjmp.texi

📁 一个C源代码分析器
💻 TEXI
字号:
@node Non-Local Exits, Signal Handling, Date and Time, Top@chapter Non-Local Exits@cindex non-local exits@cindex long jumpsSometimes when your program detects an unusual situation inside a deeplynested set of function calls, you would like to be able to immediatelyreturn to an outer level of control.  This section describes how you cando such @dfn{non-local exits} using the @code{setjmp} and @code{longjmp}functions.@menu* Intro: Non-Local Intro.        When and how to use these facilities.* Details: Non-Local Details.   Functions for nonlocal exits.* Non-Local Exits and Signals::  Portability issues.@end menu@node Non-Local Intro, Non-Local Details,  , Non-Local Exits@section Introduction to Non-Local ExitsAs an example of a situation where a non-local exit can be useful,suppose you have an interactive program that has a ``main loop'' thatprompts for and executes commands.  Suppose the ``read'' command readsinput from a file, doing some lexical analysis and parsing of the inputwhile processing it.  If a low-level input error is detected, it wouldbe useful to be able to return immediately to the ``main loop'' insteadof having to make each of the lexical analysis, parsing, and processingphases all have to explicitly deal with error situations initiallydetected by nested calls.(On the other hand, if each of these phases has to do a substantialamount of cleanup when it exits---such as closing files, deallocatingbuffers or other data structures, and the like---then it can be moreappropriate to do a normal return and have each phase do its owncleanup, because a non-local exit would bypass the intervening phases andtheir associated cleanup code entirely.  Alternatively, you could use anon-local exit but do the cleanup explicitly either before or afterreturning to the ``main loop''.)In some ways, a non-local exit is similar to using the @samp{return}statement to return from a function.  But while @samp{return} abandonsonly a single function call, transferring control back to the point atwhich it was called, a non-local exit can potentially abandon manylevels of nested function calls.You identify return points for non-local exits calling the function@code{setjmp}.  This function saves information about the executionenvironment in which the call to @code{setjmp} appears in an object oftype @code{jmp_buf}.  Execution of the program continues normally afterthe call to @code{setjmp}, but if a exit is later made to this returnpoint by calling @code{longjmp} with the corresponding @code{jmp_buf}object, control is transferred back to the point where @code{setjmp} wascalled.  The return value from @code{setjmp} is used to distinguishbetween an ordinary return and a return made by a call to@code{longjmp}, so calls to @code{setjmp} usually appear in an @samp{if}statement.Here is how the example program described above might be set up:  @smallexample@include setjmp.c.texi@end smallexampleThe function @code{abort_to_main_loop} causes an immediate transfer ofcontrol back to the main loop of the program, no matter where it iscalled from.The flow of control inside the @code{main} function may appear a littlemysterious at first, but it is actually a common idiom with@code{setjmp}.  A normal call to @code{setjmp} returns zero, so the``else'' clause of the conditional is executed.  If@code{abort_to_main_loop} is called somewhere within the execution of@code{do_command}, then it actually appears as if the @emph{same} callto @code{setjmp} in @code{main} were returning a second time with a valueof @code{-1}.@need 250So, the general pattern for using @code{setjmp} looks something like:@smallexampleif (setjmp (@var{buffer}))  /* @r{Code to clean up after premature return.} */  @dots{}else  /* @r{Code to be executed normally after setting up the return point.} */  @dots{}@end smallexample@node Non-Local Details, Non-Local Exits and Signals, Non-Local Intro, Non-Local Exits@section Details of Non-Local ExitsHere are the details on the functions and data structures used forperforming non-local exits.  These facilities are declared in@file{setjmp.h}.@pindex setjmp.h@comment setjmp.h@comment ANSI@deftp {Data Type} jmp_bufObjects of type @code{jmp_buf} hold the state information tobe restored by a non-local exit.  The contents of a @code{jmp_buf}identify a specific place to return to.@end deftp@comment setjmp.h@comment ANSI@deftypefn Macro int setjmp (jmp_buf @var{state})When called normally, @code{setjmp} stores information about theexecution state of the program in @var{state} and returns zero.  If@code{longjmp} is later used to perform a non-local exit to this@var{state}, @code{setjmp} returns a nonzero value.@end deftypefn@comment setjmp.h@comment ANSI@deftypefun void longjmp (jmp_buf @var{state}, int @var{value}) This function restores current execution to the state saved in@var{state}, and continues execution from the call to @code{setjmp} thatestablished that return point.  Returning from @code{setjmp} by means of@code{longjmp} returns the @var{value} argument that was passed to@code{longjmp}, rather than @code{0}.  (But if @var{value} is given as@code{0}, @code{setjmp} returns @code{1}).@refill@end deftypefunThere are a lot of obscure but important restrictions on the use of@code{setjmp} and @code{longjmp}.  Most of these restrictions arepresent because non-local exits require a fair amount of magic on thepart of the C compiler and can interact with other parts of the languagein strange ways.The @code{setjmp} function is actually a macro without an actualfunction definition, so you shouldn't try to @samp{#undef} it or takeits address.  In addition, calls to @code{setjmp} are safe in only thefollowing contexts:@itemize @bullet@itemAs the test expression of a selection or iterationstatement (such as @samp{if}, @samp{switch}, or @samp{while}).@itemAs one operand of a equality or comparison operator that appears as thetest expression of a selection or iteration statement.  The otheroperand must be an integer constant expression.@itemAs the operand of a unary @samp{!} operator, that appears as thetest expression of a selection or iteration statement.@itemBy itself as an expression statement.@end itemizeReturn points are valid only during the dynamic extent of the functionthat called @code{setjmp} to establish them.  If you @code{longjmp} toa return point that was established in a function that has alreadyreturned, unpredictable and disastrous things are likely to happen.You should use a nonzero @var{value} argument to @code{longjmp}.  While@code{longjmp} refuses to pass back a zero argument as the return valuefrom @code{setjmp}, this is intended as a safety net against accidentalmisuse and is not really good programming style.When you perform a non-local exit, accessible objects generally retainwhatever values they had at the time @code{longjmp} was called.  Theexception is that the values of automatic variables local to thefunction containing the @code{setjmp} call that have been changed sincethe call to @code{setjmp} are indeterminate, unless you have declaredthem @code{volatile}.@node Non-Local Exits and Signals,, Non-Local Details, Non-Local Exits@section Non-Local Exits and SignalsIn BSD Unix systems, @code{setjmp} and @code{longjmp} also save andrestore the set of blocked signals; see @ref{Blocking Signals}.  However,the POSIX.1 standard requires @code{setjmp} and @code{longjmp} not tochange the set of blocked signals, and provides an additional pair offunctions (@code{sigsetjmp} and @code{sigsetjmp}) to get the BSDbehavior.The behavior of @code{setjmp} and @code{longjmp} in the GNU library iscontrolled by feature test macros; see @ref{Feature Test Macros}.  Thedefault in the GNU system is the POSIX.1 behavior rather than the BSDbehavior.The facilities in this section are declared in the header file@file{setjmp.h}.@pindex setjmp.h@comment setjmp.h@comment POSIX.1@deftp {Data Type} sigjmp_bufThis is similar to @code{jmp_buf}, except that it can also store stateinformation about the set of blocked signals.@end deftp@comment setjmp.h@comment POSIX.1@deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs})This is similar to @code{setjmp}.  If @var{savesigs} is nonzero, the setof blocked signals is saved in @var{state} and will be restored if a@code{siglongjmp} is later performed with this @var{state}.@end deftypefun@comment setjmp.h@comment POSIX.1@deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value})This is similar to @code{longjmp} except for the type of its @var{state}argument.  If the @code{sigsetjmp} call that set this @var{state} used anonzero @var{savesigs} flag, @code{siglongjmp} also restores the set ofblocked signals.@end deftypefun

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -