<!DOCTYPE html>
<html class="client-js"><head>
  <meta charset="UTF-8">
  <title>setjmp.h</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script>
    function importScript() { return 1 } // this is to avoid the error from site.js
  </script>
  <script>let articleId = 'Setjmp.h'</script>
  <link rel="canonical" href="https://en.wikipedia.org/wiki/Setjmp.h">
  <link href="../-/mw/ext.cite.ux-enhancements.css" rel="stylesheet" type="text/css">
<link href="../-/mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="../-/mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="../-/mw/skins.minerva.base.reset|skins.minerva.content.styles|ext.cite.style|site.styles|mobile.app.pagestyles.android|mediawiki.page.gallery.styles|mediawiki.skinning.content.parsoid.css" rel="stylesheet" type="text/css">
  <link href="../-/style.css" rel="stylesheet" type="text/css"><link href="../-/content.parsoid.css" rel="stylesheet" type="text/css"><link href="../-/inserted_style.css" rel="stylesheet" type="text/css">
  <script src="../-/script.js"></script><script src="../-/masonry.min.js"></script><script src="../-/article_list_home.js"></script><script src="../-/images_loaded.min.js"></script><script src="../-/node_module/details-element-polyfill/dist/details-element-polyfill.js"></script>
</head>

<body class="mediawiki mw-hide-empty-elt ns-0 ns-subject stable skin-minerva action-view animations">
  <div id="mw-mf-viewport" class="feature-header-v2">
    <div id="mw-mf-page-center">
      <div id="content" class="mw-body">
        <a id="top"></a>
        <div id="bodyContent" class="content mw-parser-output">
          
          <div id="mw-content-text" style="direction: ltr;"><h1 class="section-heading" tabindex="0" aria-haspopup="true" data-section-id="0">
  <span class="mw-headline" id="title_0">setjmp.h</span>
</h1>
<div id="mf-section-0" class="mf-section-0" aria-pressed="true" aria-expanded="true">
  <p><b>setjmp.h</b> is a <a href="Header_file" title="Header file" class="mw-redirect">header</a> defined in the <a href="C_standard_library" title="C standard library">C standard library</a> to provide "non-local jumps": <a href="Control_flow" title="Control flow">control flow</a> that deviates from the usual <a href="Subroutine" title="Subroutine">subroutine</a> call and return sequence. The complementary functions <b><code>setjmp</code></b> and <b><code>longjmp</code></b> provide this functionality.</p>


<p><span>
</span><meta property="mw:PageProp/displaytitle" content="setjmp.h"></p>

<style data-mw-deduplicate="TemplateStyles:r1002487873">.mw-parser-output .sidebar{width:22em;float:right;clear:right;margin:0.5em 0 1em 1em;background:#f8f9fa;border:1px solid #aaa;padding:0.2em;border-spacing:0.4em 0;text-align:center;line-height:1.4em;font-size:88%}.mw-parser-output .sidebar a{white-space:nowrap}.mw-parser-output .sidebar-wraplinks a{white-space:normal}.mw-parser-output .sidebar-subgroup{width:100%;margin:0;border-spacing:0}.mw-parser-output .sidebar-left{float:left;clear:left;margin:0.5em 1em 1em 0}.mw-parser-output .sidebar-none{float:none;clear:both;margin:0.5em 1em 1em 0}.mw-parser-output .sidebar-outer-title{padding-bottom:0.2em;font-size:125%;line-height:1.2em;font-weight:bold}.mw-parser-output .sidebar-top-image{padding:0.4em 0}.mw-parser-output .sidebar-top-caption,.mw-parser-output .sidebar-pretitle-with-top-image,.mw-parser-output .sidebar-caption{padding-top:0.2em;line-height:1.2em}.mw-parser-output .sidebar-pretitle{padding-top:0.4em;line-height:1.2em}.mw-parser-output .sidebar-title,.mw-parser-output .sidebar-title-with-pretitle{padding:0.2em 0.4em;font-size:145%;line-height:1.2em}.mw-parser-output .sidebar-title-with-pretitle{padding-top:0}.mw-parser-output .sidebar-image{padding:0.2em 0 0.4em}.mw-parser-output .sidebar-heading{padding:0.1em}.mw-parser-output .sidebar-content{padding:0 0.1em 0.4em}.mw-parser-output .sidebar-content-with-subgroup{padding:0.1em 0 0.2em}.mw-parser-output .sidebar-above,.mw-parser-output .sidebar-below{padding:0.3em 0.4em;font-weight:bold}.mw-parser-output .sidebar-collapse .sidebar-above,.mw-parser-output .sidebar-collapse .sidebar-below{border-top:1px solid #aaa;border-bottom:1px solid #aaa}.mw-parser-output .sidebar-navbar{text-align:right;font-size:115%}.mw-parser-output .sidebar-collapse .sidebar-navbar{padding-top:0.6em}.mw-parser-output .sidebar-collapse .mw-collapsible-toggle{margin-top:0.2em}.mw-parser-output .sidebar-list-title{text-align:left;font-weight:bold;line-height:1.6em;font-size:105%}@media(max-width:720px){body.mediawiki .mw-parser-output .sidebar{width:100%!important;clear:both;float:none;margin-left:0!important;margin-right:0!important}}</style><table class="sidebar vertical-navbox nomobile"><tbody><tr><th class="sidebar-title"><a href="C_standard_library" title="C standard library">C standard library</a></th></tr><tr><th class="sidebar-heading">
General topics</th></tr><tr><td class="sidebar-content" style="text-align: left">
<ul><li><a href="C_data_types" title="C data types">Data types</a></li>
<li><a href="C_character_classification" title="C character classification">Character classification</a></li>
<li><a href="C_string_handling" title="C string handling">Strings</a></li>
<li><a href="C_mathematical_functions" title="C mathematical functions">Mathematics</a></li>
<li><a href="C_file_input/output" title="C file input/output">File input/output</a></li>
<li><a href="C_date_and_time_functions" title="C date and time functions">Date/time</a></li>
<li><a href="C_localization_functions" title="C localization functions">Localization</a></li>
<li><a href="C_dynamic_memory_allocation" title="C dynamic memory allocation">Memory allocation</a></li>
<li><a href="C_process_control" title="C process control">Process control</a></li>
<li><a href="C_signal_handling" title="C signal handling">Signals</a></li>
<li><a href="C_alternative_tokens" title="C alternative tokens">Alternative tokens</a></li></ul></td>
</tr><tr><th class="sidebar-heading">
Miscellaneous headers</th></tr><tr><td class="sidebar-content" style="text-align: left">
<ul><li><style data-mw-deduplicate="TemplateStyles:r886049734">.mw-parser-output .monospaced{font-family:monospace,monospace}</style><span class="monospaced">&lt;<a href="Assert.h" title="Assert.h">assert.h</a>&gt;</span></li>
<li><span class="monospaced">&lt;<a href="Errno.h" title="Errno.h">errno.h</a>&gt;</span></li>
<li><span class="monospaced">&lt;<a href="Setjmp.h" title="Setjmp.h">setjmp.h</a>&gt;</span></li>
<li><span class="monospaced">&lt;<a href="Stdarg.h" title="Stdarg.h">stdarg.h</a>&gt;</span></li></ul></td>
</tr><tr><td class="sidebar-navbar"><style data-mw-deduplicate="TemplateStyles:r992953826">.mw-parser-output .navbar{display:inline;font-size:88%;font-weight:normal}.mw-parser-output .navbar-collapse{float:left;text-align:left}.mw-parser-output .navbar-boxtext{word-spacing:0}.mw-parser-output .navbar ul{display:inline-block;white-space:nowrap;line-height:inherit}.mw-parser-output .navbar-brackets::before{margin-right:-0.125em;content:"[ "}.mw-parser-output .navbar-brackets::after{margin-left:-0.125em;content:" ]"}.mw-parser-output .navbar li{word-spacing:-0.125em}.mw-parser-output .navbar-mini abbr{font-variant:small-caps;border-bottom:none;text-decoration:none;cursor:inherit}.mw-parser-output .navbar-ct-full{font-size:114%;margin:0 7em}.mw-parser-output .navbar-ct-mini{font-size:114%;margin:0 4em}.mw-parser-output .infobox .navbar{font-size:100%}.mw-parser-output .navbox .navbar{display:block;font-size:100%}.mw-parser-output .navbox-title .navbar{float:left;text-align:left;margin-right:0.5em}</style></td></tr></tbody></table>

<p>A typical use of <code>setjmp</code>/<code>longjmp</code> is implementation of an <a href="Exception_mechanism" title="Exception mechanism" class="mw-redirect">exception mechanism</a> that exploits the ability of <code>longjmp</code> to reestablish program or thread state, even across multiple levels of function calls. A less common use of <code>setjmp</code> is to create syntax similar to <a href="Coroutine#Implementations_for_C" title="Coroutine">coroutines</a>.</p>


</div><details data-level="2" open="">
    <summary class="section-heading"><h2 id="Member_functions">Member functions</h2></summary>
    
<table class="wikitable">
<tbody><tr>
<td><code>int setjmp(jmp_buf<span>&nbsp;</span>env)</code></td><td>Sets up the local <code>jmp_buf</code> buffer and initializes it for the jump. This routine<span class="mw-ref reference" id="cite_ref-macro_1-0"><a href="#cite_note-macro-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></span> saves the program's calling environment in the environment buffer specified by the <code>env</code> argument for later use by <code>longjmp</code>. If the return is from a direct invocation, <code>setjmp</code> returns 0. If the return is from a call to <code>longjmp</code>, <code>setjmp</code> returns a nonzero value.</td></tr>
<tr>
<td><code>void longjmp(jmp_buf<span>&nbsp;</span>env, int<span>&nbsp;</span>value)</code></td><td>Restores the context of the environment buffer <code>env</code> that was saved by invocation of the <code>setjmp</code> routine<span class="mw-ref reference" id="cite_ref-macro_1-1"><a href="#cite_note-macro-1" style="counter-reset: mw-Ref 1;"><span class="mw-reflink-text">[1]</span></a></span> in the same invocation of the program. Invoking <code>longjmp</code> from a nested signal handler is <a href="Undefined_behavior" title="Undefined behavior">undefined</a>. The value specified by <code>value</code> is passed from <code>longjmp</code> to <code>setjmp</code>. After <code>longjmp</code> is completed, program execution continues as if the corresponding invocation of <code>setjmp</code> had just returned. If the <code>value</code> passed to <code>longjmp</code> is 0, <code>setjmp</code> will behave as if it had returned 1; otherwise, it will behave as if it had returned <code>value</code>.</td></tr>
</tbody></table>

<p><code>setjmp</code> saves the current environment (the program state), at some point of program execution, into a platform-specific data structure (<code>jmp_buf</code>) that can be used at some later point of program execution by <code>longjmp</code> to restore the program state to that saved by <code>setjmp</code> into <code>jmp_buf</code>. This process can be imagined to be a "jump" back to the point of program execution where <code>setjmp</code> saved the environment. The (apparent) <a href="Return_value" title="Return value" class="mw-redirect">return value</a> from <code>setjmp</code> indicates whether control reached that point normally (zero) or from a call to <code>longjmp</code> (nonzero). This leads to a common <a href="Programming_idiom" title="Programming idiom">idiom</a>: <code class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><span class="k">if</span><span class="p">(</span> <span class="n">setjmp</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="p">){</span><span class="cm">/* handle longjmp(x) */</span><span class="p">}</span></code>.</p>

<p><a href="POSIX" title="POSIX">POSIX</a>.1 does not specify whether <code>setjmp</code> and <code>longjmp</code> save and restore the current set of blocked <a href="Signal_(computing)" title="Signal (computing)" class="mw-redirect">signals</a>; if a program employs signal handling it should use POSIX's <code>sigsetjmp</code>/<code>siglongjmp</code>.</p>


    
</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="Member_types">Member types</h2></summary>
    
<table class="wikitable">
<tbody><tr>
<td><code>jmp_buf</code></td><td>An array type, such as <code>struct __jmp_buf_tag[1]</code>,<span class="mw-ref reference" id="cite_ref-2"><a href="#cite_note-2" style="counter-reset: mw-Ref 2;"><span class="mw-reflink-text">[2]</span></a></span> suitable for holding the information needed to restore a calling environment.</td></tr>
</tbody></table>

<p>The C99 Rationale describes <code>jmp_buf</code> as being an array type for <a href="Backward_compatibility" title="Backward compatibility">backward compatibility</a>; existing code refers to <code>jmp_buf</code> storage locations by name (without the <code>&amp;</code> address-of operator), which is only possible for array types.<span class="mw-ref reference" id="cite_ref-rationale_3-0"><a href="#cite_note-rationale-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></span></p>


    
</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="Caveats_and_limitations">Caveats and limitations</h2></summary>
    
<p>When a "non-local goto" is executed via <code>setjmp</code>/<code>longjmp</code> in <a href="C%2B%2B" title="C++">C++</a>, normal "<a href="Stack_unwinding" title="Stack unwinding" class="mw-redirect">stack unwinding</a>" does not occur. Therefore, any required cleanup actions will not occur either. This could include closing <a href="File_descriptor" title="File descriptor">file descriptors</a>, flushing <a href="Buffer_(computer_science)" title="Buffer (computer science)" class="mw-redirect">buffers</a>, or freeing <a href="Dynamic_memory_allocation" title="Dynamic memory allocation" class="mw-redirect">heap-allocated memory</a>.</p>

<p>If the function in which <code>setjmp</code> was called returns, it is no longer possible to safely use <code>longjmp</code> with the corresponding <code>jmp_buf</code> object. This is because the <a href="Stack_frame" title="Stack frame" class="mw-redirect">stack frame</a> is invalidated when the function returns. Calling <code>longjmp</code> restores the <a href="Stack_pointer" title="Stack pointer" class="mw-redirect">stack pointer</a>, which—because the function returned—would point to a non-existent and potentially overwritten or corrupted stack frame.<span class="mw-ref reference" id="cite_ref-4"><a href="#cite_note-4" style="counter-reset: mw-Ref 4;"><span class="mw-reflink-text">[4]</span></a></span><span class="mw-ref reference" id="cite_ref-5"><a href="#cite_note-5" style="counter-reset: mw-Ref 5;"><span class="mw-reflink-text">[5]</span></a></span></p>

<p>Similarly, <a href="C99" title="C99">C99</a> does not require that <code>longjmp</code> preserve the current stack frame. This means that jumping into a function which was exited via a call to <code>longjmp</code> is undefined.<span class="mw-ref reference" id="cite_ref-ISO/IEC_9899:1999_6-0"><a href="#cite_note-ISO/IEC_9899:1999-6" style="counter-reset: mw-Ref 6;"><span class="mw-reflink-text">[6]</span></a></span> However, most implementations of <code>longjmp</code> leave the stack frame intact, allowing <code>setjmp</code> and <code>longjmp</code> to be used to jump back-and-forth between two or more functions—a feature exploited for <a href="#Cooperative_multitasking">multitasking</a>.</p>

<p>Compared to mechanisms in higher-level programming languages such as <a href="Python_(programming_language)" title="Python (programming language)">Python</a>, <a href="Java_(programming_language)" title="Java (programming language)">Java</a>, <a href="C%2B%2B" title="C++">C++</a>, <a href="C_Sharp_(programming_language)" title="C Sharp (programming language)">C#</a>, and even pre-C languages such as <a href="Algol_60" title="Algol 60" class="mw-redirect">Algol 60</a>, the technique of using <code>setjmp</code>/<code>longjmp</code> to implement an exception mechanism is cumbersome. These languages provide more powerful <a href="Exception_handling" title="Exception handling">exception handling</a> techniques, while languages such as <a href="Scheme_(programming_language)" title="Scheme (programming language)">Scheme</a>, <a href="Smalltalk" title="Smalltalk">Smalltalk</a>, and <a href="Haskell_(programming_language)" title="Haskell (programming language)">Haskell</a> provide even more general <a href="Continuation" title="Continuation">continuation</a>-handling constructs.</p>


    
</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="Example_usage">Example usage</h2></summary>
    


    <details data-level="3" open="">
    <summary class="section-heading"><h3 id="Simple_example">Simple example</h3></summary>
    
<p>The example below shows the basic idea of setjmp. There, <code>main()</code> calls <code>first()</code>, which in turn calls <code>second()</code>. Then, <code>second()</code> jumps back into <code>main()</code>, skipping <code>first()</code>'s call of <code>printf()</code>.</p>

<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;setjmp.h&gt;</span>

<span class="k">static</span> <span class="kt">jmp_buf</span> <span class="n">buf</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">second</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"second</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>         <span class="c1">// prints</span>
    <span class="n">longjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">,</span><span class="mi">1</span><span class="p">);</span>             <span class="c1">// jumps back to where setjmp was called - making setjmp now return 1</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">first</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">second</span><span class="p">();</span>
    <span class="n">printf</span><span class="p">(</span><span class="s">"first</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>          <span class="c1">// does not print</span>
<span class="p">}</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>   
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">setjmp</span><span class="p">(</span><span class="n">buf</span><span class="p">))</span>
        <span class="n">first</span><span class="p">();</span>                <span class="c1">// when executed, setjmp returned 0</span>
    <span class="k">else</span>                        <span class="c1">// when longjmp jumps back, setjmp returns 1</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"main</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>       <span class="c1">// prints</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>

<p>When executed, the above program will output:</p>

<div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre>second
main
</pre></div>

<p>Notice that although the <code>first()</code> subroutine gets called, "<code>first</code>" is never printed. "<code>main</code>" gets printed as the conditional statement <code>if (!setjmp(buf))</code> is executed a second time.</p>


</details>
<details data-level="3" open="">
    <summary class="section-heading"><h3 id="Exception_handling">Exception handling</h3></summary>
    
<p>In this example, <code>setjmp</code> is used to bracket exception handling, like <a href="Try-catch_block" title="Try-catch block" class="mw-redirect"><code>try</code></a> in some other languages. The call to <code>longjmp</code> is analogous to a <code>throw</code> statement, allowing an exception to return an error status directly to the <code>setjmp</code>. The following code adheres to the <a href="C_(programming_language)#C99" title="C (programming language)">1999 ISO C standard</a> and <a href="Single_UNIX_Specification" title="Single UNIX Specification">Single UNIX Specification</a> by invoking <code>setjmp</code> in a limited range of contexts:<span class="mw-ref reference" id="cite_ref-SUS_7-0"><a href="#cite_note-SUS-7" style="counter-reset: mw-Ref 7;"><span class="mw-reflink-text">[7]</span></a></span></p>
<ul><li>As the condition to an <code>if</code>, <code>switch</code> or iteration statement</li>
<li>As above in conjunction with a single <code>!</code> or comparison with an integer constant</li>
<li>As a statement (with the return value unused)</li></ul>

<p>Following these rules can make it easier for the implementation to create the environment buffer, which can be a sensitive operation.<span class="mw-ref reference" id="cite_ref-rationale_3-1"><a href="#cite_note-rationale-3" style="counter-reset: mw-Ref 3;"><span class="mw-reflink-text">[3]</span></a></span> More general use of <code>setjmp</code> can cause undefined behaviour, such as corruption of local variables; conforming compilers and environments are not required to protect or even warn against such usage. However, slightly more sophisticated idioms such as <code>switch ((exception_type = setjmp(env))) { }</code> are common in literature and practice, and remain relatively portable. A simple conforming methodology is presented below, where an additional variable is maintained along with the state buffer. This variable could be elaborated into a structure incorporating the buffer itself.</p>

<p>In a more modern-looking example, the usual "try" block would be implemented as a setjmp (with some preparation code for multilevel jumps, as seen in <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">first</code>), the "throw" as longjmp with the optional parameter as the exception, and the "catch" as the "else" block under "try".</p>

<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="cp">#include</span> <span class="cpf">&lt;setjmp.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span>

<span class="k">static</span> <span class="kt">void</span> <span class="n">first</span><span class="p">();</span>
<span class="k">static</span> <span class="kt">void</span> <span class="n">second</span><span class="p">();</span>

<span class="cm">/* Use a file scoped static variable for the exception stack so we can access</span>
<span class="cm"> * it anywhere within this translation unit. */</span>
<span class="k">static</span> <span class="kt">jmp_buf</span> <span class="n">exception_env</span><span class="p">;</span>
<span class="k">static</span> <span class="kt">int</span> <span class="n">exception_type</span><span class="p">;</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">char</span><span class="o">*</span> <span class="k">volatile</span> <span class="n">mem_buffer</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">setjmp</span><span class="p">(</span><span class="n">exception_env</span><span class="p">))</span> <span class="p">{</span>
        <span class="c1">// if we get here there was an exception</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"first failed, exception type: %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">exception_type</span><span class="p">);</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="c1">// Run code that may signal failure via longjmp.</span>
        <span class="n">puts</span><span class="p">(</span><span class="s">"calling first"</span><span class="p">);</span>
        <span class="n">first</span><span class="p">();</span>

        <span class="n">mem_buffer</span> <span class="o">=</span> <span class="n">malloc</span><span class="p">(</span><span class="mi">300</span><span class="p">);</span> <span class="c1">// allocate a resource</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"%s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">strcpy</span><span class="p">(</span><span class="n">mem_buffer</span><span class="p">,</span> <span class="s">"first succeeded"</span><span class="p">));</span> <span class="c1">// not reached</span>
    <span class="p">}</span>

    <span class="n">free</span><span class="p">(</span><span class="n">mem_buffer</span><span class="p">);</span> <span class="c1">// NULL can be passed to free, no operation is performed</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">static</span> <span class="kt">void</span> <span class="n">first</span><span class="p">()</span> <span class="p">{</span>
    <span class="kt">jmp_buf</span> <span class="n">my_env</span><span class="p">;</span>

    <span class="n">puts</span><span class="p">(</span><span class="s">"entering first"</span><span class="p">);</span> <span class="c1">// reached</span>

    <span class="n">memcpy</span><span class="p">(</span><span class="n">my_env</span><span class="p">,</span> <span class="n">exception_env</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">my_env</span><span class="p">);</span>

    <span class="k">switch</span> <span class="p">(</span><span class="n">setjmp</span><span class="p">(</span><span class="n">exception_env</span><span class="p">))</span> <span class="p">{</span>
        <span class="k">case</span> <span class="mi">3</span><span class="o">:</span> <span class="c1">// if we get here there was an exception.</span>
            <span class="n">puts</span><span class="p">(</span><span class="s">"second failed, exception type: 3; remapping to type 1"</span><span class="p">);</span>
            <span class="n">exception_type</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>

        <span class="k">default</span><span class="o">:</span> <span class="c1">// fall through</span>
            <span class="n">memcpy</span><span class="p">(</span><span class="n">exception_env</span><span class="p">,</span> <span class="n">my_env</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">exception_env</span><span class="p">);</span> <span class="c1">// restore exception stack</span>
            <span class="n">longjmp</span><span class="p">(</span><span class="n">exception_env</span><span class="p">,</span> <span class="n">exception_type</span><span class="p">);</span> <span class="c1">// continue handling the exception</span>

        <span class="k">case</span> <span class="mi">0</span><span class="o">:</span> <span class="c1">// normal, desired operation</span>
            <span class="n">puts</span><span class="p">(</span><span class="s">"calling second"</span><span class="p">);</span> <span class="c1">// reached </span>
            <span class="n">second</span><span class="p">();</span>
            <span class="n">puts</span><span class="p">(</span><span class="s">"second succeeded"</span><span class="p">);</span> <span class="c1">// not reached</span>
    <span class="p">}</span>

    <span class="n">memcpy</span><span class="p">(</span><span class="n">exception_env</span><span class="p">,</span> <span class="n">my_env</span><span class="p">,</span> <span class="k">sizeof</span> <span class="n">exception_env</span><span class="p">);</span> <span class="c1">// restore exception stack</span>

    <span class="n">puts</span><span class="p">(</span><span class="s">"leaving first"</span><span class="p">);</span> <span class="c1">// never reached</span>
<span class="p">}</span>

<span class="k">static</span> <span class="kt">void</span> <span class="n">second</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">puts</span><span class="p">(</span><span class="s">"entering second"</span> <span class="p">);</span> <span class="c1">// reached</span>

    <span class="n">exception_type</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
    <span class="n">longjmp</span><span class="p">(</span><span class="n">exception_env</span><span class="p">,</span> <span class="n">exception_type</span><span class="p">);</span> <span class="c1">// declare that the program has failed</span>

    <span class="n">puts</span><span class="p">(</span><span class="s">"leaving second"</span><span class="p">);</span> <span class="c1">// not reached</span>
<span class="p">}</span>
</pre></div>

<p>This program's output is:</p>
<pre>calling first
entering first
calling second
entering second
second failed, exception type: 3; remapping to type 1
first failed, exception type: 1
</pre>

<p>Although the <code class="mw-highlight mw-highlight-lang-text mw-content-ltr" style="" dir="ltr">exception_type</code> variable is technically not needed here since setjmp returns what nonzero value longjmp was called with (as in second and first), in practice a more elaborate global object would be used to accommodate richer exceptions.</p>

<p>In the real world, setjmp-longjmp (sjlj) used to be the standard way of exception handling in third-party Windows C++ compilers (namely <a href="MinGW" title="MinGW">MinGW</a>), since the native Structured Exception Handling is poorly documented in general and was also patented on 32-bit Windows up until 2014.</p>


</details>
<details data-level="3" open="">
    <summary class="section-heading"><h3 id="Cooperative_multitasking">Cooperative multitasking</h3></summary>
    
<p><a href="C99" title="C99">C99</a> provides that <code>longjmp</code> is guaranteed to work only when the destination is a calling function, i.e., that the destination scope is guaranteed to be intact. Jumping to a function that has already terminated by <code>return</code> or <code>longjmp</code> is undefined.<span class="mw-ref reference" id="cite_ref-ISO/IEC_9899:1999_6-1"><a href="#cite_note-ISO/IEC_9899:1999-6" style="counter-reset: mw-Ref 6;"><span class="mw-reflink-text">[6]</span></a></span> However, most implementations of <code>longjmp</code> do not specifically destroy local variables when performing the jump. Since the context survives until its local variables are erased, it could actually be restored by <code>setjmp</code>. In many environments (such as <a href="https://www.gnu.org/software/pth/related.html" class="external text external">Really Simple Threads</a> and <a href="https://github.com/simait/TinyTimber" class="external text external">TinyTimbers</a>), idioms such as <code>if(!setjmp(child_env)) longjmp(caller_env);</code> can allow a called function to effectively pause-and-resume at a <code>setjmp</code>.</p>

<p>This is exploited by thread libraries to provide <a href="Cooperative_multitasking" title="Cooperative multitasking">cooperative multitasking</a> facilities without using <code><a href="Setcontext" title="Setcontext">setcontext</a></code> or other <a href="Fiber_(computer_science)" title="Fiber (computer science)">fiber</a> facilities.  Whereas <code>setcontext</code> is a library service which can create an execution context in heap-allocated memory and can support other services such as <a href="Buffer_overflow_protection" title="Buffer overflow protection">buffer overflow protection</a>, abuse of <code>setjmp</code> is implemented by the programmer, who may reserve memory on the stack and fail to notify the library or operating system of the new operating context. On the other hand, a library's implementation of <code>setcontext</code> may internally use <code>setjmp</code> in a fashion similar to this example to save and restore a context, after it has been initialised somehow.</p>

<p>Considering that <code>setjmp</code> to a child function will generally work unless sabotaged, and <code>setcontext</code>, as part of <a href="POSIX" title="POSIX">POSIX</a>, is not required to be provided by C implementations, this mechanism may be portable where the <code>setcontext</code> alternative fails.</p>

<p>Since no exception will be generated upon overflow of one of the multiple stacks in such a mechanism, it is essential to overestimate the space required for each context, including the one containing <code>main()</code> and including space for any signal handlers that might interrupt regular execution. Exceeding the allocated space will corrupt the other contexts, usually with the outermost functions first. Unfortunately, systems requiring this kind of programming strategy are often also small ones with limited resources.</p>

<div class="mw-highlight mw-highlight-lang-c mw-content-ltr" dir="ltr"><pre><span class="cp">#include</span> <span class="cpf">&lt;setjmp.h&gt;</span>
<span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span>

<span class="kt">jmp_buf</span> <span class="n">mainTask</span><span class="p">,</span> <span class="n">childTask</span><span class="p">;</span>

<span class="kt">void</span> <span class="nf">call_with_cushion</span><span class="p">();</span>
<span class="kt">void</span> <span class="nf">child</span><span class="p">();</span>

<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">setjmp</span><span class="p">(</span><span class="n">mainTask</span><span class="p">))</span> <span class="p">{</span>
        <span class="n">call_with_cushion</span><span class="p">();</span> <span class="c1">// child never returns, yield</span>
    <span class="p">}</span> <span class="c1">// execution resumes after this "}" after first time that child yields</span>

    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"Parent</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">setjmp</span><span class="p">(</span><span class="n">mainTask</span><span class="p">))</span>
            <span class="n">longjmp</span><span class="p">(</span><span class="n">childTask</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// yield - note that this is undefined under C99</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">call_with_cushion</span><span class="p">()</span> <span class="p">{</span>
    <span class="kt">char</span> <span class="n">space</span><span class="p">[</span><span class="mi">1000</span><span class="p">];</span> <span class="c1">// Reserve enough space for main to run</span>
    <span class="n">space</span><span class="p">[</span><span class="mi">999</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="c1">// Do not optimize array out of existence</span>
    <span class="n">child</span><span class="p">();</span>
<span class="p">}</span>

<span class="kt">void</span> <span class="nf">child</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">while</span> <span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">printf</span><span class="p">(</span><span class="s">"Child loop begin</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
        
        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">setjmp</span><span class="p">(</span><span class="n">childTask</span><span class="p">))</span>
            <span class="n">longjmp</span><span class="p">(</span><span class="n">mainTask</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// yield - invalidates childTask in C99</span>

        <span class="n">printf</span><span class="p">(</span><span class="s">"Child loop end</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>

        <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">setjmp</span><span class="p">(</span><span class="n">childTask</span><span class="p">))</span>
            <span class="n">longjmp</span><span class="p">(</span><span class="n">mainTask</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span> <span class="c1">// yield - invalidates childTask in C99</span>
    <span class="p">}</span>

    <span class="cm">/* Don't return. Instead we should set a flag to indicate that main()</span>
<span class="cm">       should stop yielding to us and then longjmp(mainTask, 1) */</span>
<span class="p">}</span>
</pre></div>


</details>

</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="See_also">See also</h2></summary>
    
<style data-mw-deduplicate="TemplateStyles:r936637989">.mw-parser-output .portal{border:solid #aaa 1px;padding:0}.mw-parser-output .portal.tleft{margin:0.5em 1em 0.5em 0}.mw-parser-output .portal.tright{margin:0.5em 0 0.5em 1em}.mw-parser-output .portal>ul{display:table;box-sizing:border-box;padding:0.1em;max-width:175px;background:#f9f9f9;font-size:85%;line-height:110%;font-style:italic;font-weight:bold}.mw-parser-output .portal>ul>li{display:table-row}.mw-parser-output .portal>ul>li>span:first-child{display:table-cell;padding:0.2em;vertical-align:middle;text-align:center}.mw-parser-output .portal>ul>li>span:last-child{display:table-cell;padding:0.2em 0.2em 0.2em 0.3em;vertical-align:middle}</style>
<ul><li><a href="Continuation" title="Continuation">Continuation</a></li>
<li><a href="Setcontext" title="Setcontext">setcontext</a></li></ul>


    
</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="References">References</h2></summary>
    
<div class="reflist columns references-column-width" style="column-width: 30em; list-style-type: decimal;">
<ol class="mw-references references"><li id="cite_note-macro-1"> <span id="mw-reference-text-cite_note-macro-1" class="mw-reference-text">ISO C states that <code>setjmp</code> must be implemented as a macro, but POSIX explicitly states that it is undefined whether <code>setjmp</code> is a macro or a function.</span></li><li id="cite_note-2"> <span id="mw-reference-text-cite_note-2" class="mw-reference-text">This is the type used by the <a href="GNU_C_Library" title="GNU C Library">GNU C Library</a>, version 2.7</span></li><li id="cite_note-rationale-3"> <span id="mw-reference-text-cite_note-rationale-3" class="mw-reference-text"><a href="http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf" class="external text external">C99 Rationale, version 5.10, April 2003</a>, section 7.13</span></li><li id="cite_note-4"> <span id="mw-reference-text-cite_note-4" class="mw-reference-text"><a href="http://www.cs.utk.edu/~mbeck/classes/cs560/360/notes/Setjmp/lecture.html" class="external text external">CS360 Lecture Notes — Setjmp and Longjmp</a></span></li><li id="cite_note-5"> <span id="mw-reference-text-cite_note-5" class="mw-reference-text"><a href="http://www.uwm.edu/cgi-bin/IMT/wwwman?topic=setjmp(3)&amp;msection=" class="external text external">setjmp(3)</a> <a href="https://web.archive.org/web/20090726081425/http://www.uwm.edu/cgi-bin/IMT/wwwman?topic=setjmp%283%29&amp;msection=" class="external text external">Archived</a><span> 2009-07-26 at the </span><a href="Wayback_Machine" title="Wayback Machine">Wayback Machine</a></span></li><li id="cite_note-ISO/IEC_9899:1999-6"> <span id="mw-reference-text-cite_note-ISO/IEC_9899:1999-6" class="mw-reference-text"><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf" class="external text external">ISO/IEC 9899:1999</a>, 2005, 7.13.2.1:2 and footnote 211</span></li><li id="cite_note-SUS-7"> <span id="mw-reference-text-cite_note-SUS-7" class="mw-reference-text"><span class="neverexpand"><code><a href="https://www.opengroup.org/onlinepubs/9699919799/functions/setjmp.html" class="external text external">setjmp</a></code></span><span>:</span><span>&nbsp;</span><span>set jump point for a non-local goto</span><span>&nbsp;</span><span>–</span><span>&nbsp;</span><span>System Interfaces Reference, </span><a href="Single_Unix_Specification" title="Single Unix Specification" class="mw-redirect">The Single UNIX Specification</a><span>, Issue 7 from </span><a href="The_Open_Group" title="The Open Group">The Open Group</a></span></li></ol></div>


    
</details><details data-level="2" open="">
    <summary class="section-heading"><h2 id="External_links">External links</h2></summary>
    
<ul><li><span class="neverexpand"><code><a href="https://www.opengroup.org/onlinepubs/9699919799/functions/setjmp.html" class="external text external">setjmp</a></code></span><span>:</span><span>&nbsp;</span><span>set jump point for a non-local goto</span><span>&nbsp;</span><span>–</span><span>&nbsp;</span><span>System Interfaces Reference, </span><a href="Single_Unix_Specification" title="Single Unix Specification" class="mw-redirect">The Single UNIX Specification</a><span>, Issue 7 from </span><a href="The_Open_Group" title="The Open Group">The Open Group</a></li>
<li><a href="http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html" class="external text external">Exceptions in C with Longjmp and Setjmp</a></li>
<li><a href="http://osdir.com/ml/gnu.mingw.msys/2006-05/msg00014.html" class="external text external">is there sigsetjmp/siglongjmp (again)</a> (about this functions in <a href="Mingw" title="Mingw" class="mw-redirect">mingw</a>/<a href="MSYS" title="MSYS" class="mw-redirect">MSYS</a>)</li></ul>




    
</details><!--htdig_noindex--><div><div style="clear:both; background-image:linear-gradient(180deg, #E8E8E8, white); border-top: dashed 2px #AAAAAA; padding: 0.5em 0.5em 0.5em 0.5em; margin-top: 1em; direction: ltr;">
    This article is issued from <a class="external text" title="Last edited on 2020-11-19" href="https://en.wikipedia.org/wiki/?title=Setjmp.h&amp;oldid=989491388">Wikipedia</a>. The text is licensed under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/">Creative Commons - Attribution - Sharealike</a>. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
        </div>
      </div>
    </div>
  </div>
  <script src="../-/mw/jsConfigVars.js"></script>
  <script src="../-/mw/startup.js"></script>
<script src="../-/mw/jquery.js"></script>
<script src="../-/mw/mediawiki.js"></script>
<script src="../-/mw/site.js"></script>
<script src="../-/mw/ext.cite.ux-enhancements.js"></script>



</body></html>