<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Issue 1265: longjmp and destructors</title>
<meta property="og:title" content="Issue 1265: longjmp and destructors">
<meta property="og:description" content="C++ library issue. Status: NAD">
<meta property="og:url" content="https://cplusplus.github.io/LWG/issue1265.html">
<meta property="og:type" content="website">
<meta property="og:image" content="http://cplusplus.github.io/LWG/images/cpp_logo.png">
<meta property="og:image:alt" content="C++ logo">
<style>
  p {text-align:justify}
  li {text-align:justify}
  pre code.backtick::before { content: "`" }
  pre code.backtick::after { content: "`" }
  blockquote.note
  {
    background-color:#E0E0E0;
    padding-left: 15px;
    padding-right: 15px;
    padding-top: 1px;
    padding-bottom: 1px;
  }
  ins {background-color:#A0FFA0}
  del {background-color:#FFA0A0}
  table.issues-index { border: 1px solid; border-collapse: collapse; }
  table.issues-index th { text-align: center; padding: 4px; border: 1px solid; }
  table.issues-index td { padding: 4px; border: 1px solid; }
  table.issues-index td:nth-child(1) { text-align: right; }
  table.issues-index td:nth-child(2) { text-align: left; }
  table.issues-index td:nth-child(3) { text-align: left; }
  table.issues-index td:nth-child(4) { text-align: left; }
  table.issues-index td:nth-child(5) { text-align: center; }
  table.issues-index td:nth-child(6) { text-align: center; }
  table.issues-index td:nth-child(7) { text-align: left; }
  table.issues-index td:nth-child(5) span.no-pr { color: red; }
  @media (prefers-color-scheme: dark) {
     html {
        color: #ddd;
        background-color: black;
     }
     ins {
        background-color: #225522
     }
     del {
        background-color: #662222
     }
     a {
        color: #6af
     }
     a:visited {
        color: #6af
     }
     blockquote.note
     {
        background-color: rgba(255, 255, 255, .10)
     }
  }
</style>
</head>
<body>
<hr>
<p><em>This page is a snapshot from the LWG issues list, see the <a href="lwg-active.html">Library Active Issues List</a> for more information and the meaning of <a href="lwg-active.html#NAD">NAD</a> status.</em></p>
<h3 id="1265"><a href="lwg-closed.html#1265">1265</a>. <code>longjmp</code> and destructors</h3>
<p><b>Section:</b> 17.14 <a href="https://wg21.link/support.runtime">[support.runtime]</a> <b>Status:</b> <a href="lwg-active.html#NAD">NAD</a>
 <b>Submitter:</b> Sean Hunt <b>Opened:</b> 2009-11-16 <b>Last modified:</b> 2016-01-28</p>
<p><b>Priority: </b>Not Prioritized
</p>
<p><b>View all other</b> <a href="lwg-index.html#support.runtime">issues</a> in [support.runtime].</p>
<p><b>View all issues with</b> <a href="lwg-status.html#NAD">NAD</a> status.</p>
<p><b>Discussion:</b></p>
<p>
17.14 <a href="https://wg21.link/support.runtime">[support.runtime]</a>/4 says that <code>longjmp</code> is undefined if
unwinding by the mechanism used by catch and throw would invoke any nontrivial
destructors. However, the text as written is rather vague, in particular when
dealing with <code>catch(...)</code>:
</p>

<blockquote><pre>
void foo() {
  jump_buf buf;
  non_trivial_dtor n1; // 1
  if (!setjmp(buf)) {
    non_trivial_dtor n2; // 2
    try {
      longjmp(buf, 1);
    } catch (...) {
    }
  }
}
</pre></blockquote>

<p>
My interpretation of the meaning of 17.14 <a href="https://wg21.link/support.runtime">[support.runtime]</a>/4 is that
declaration 2, but not 1, would cause the <code>longjmp</code> to be undefined
behavior. However,  it's not entirely clear from the text. Arguably, replacing
the <code>setjmp</code> and <code>longjmp</code> with <code>catch</code> would still cause
the destructor for <code>n1</code> to be called after the unwinding, which would
lead to undefined behavior. This is clearly not an intended consequence of the
wording. However, it is probably still UB, as <code>n1</code> now has
"indeterminate" value, and running its destructor on <code>foo</code>'s exit will
cause Bad Things.
</p>

<p>
Declarations 2 has a more interesting issue. The <code>catch(...)</code> muddles up
the definition that uses <code>throw</code> and <code>catch</code> - if
<code>longjmp()</code> were indeed a <code>throw</code>, control would never return to
the <code>setjmp</code>. As such, <code>n2</code>'s destructor wouldn't be called
(except by the argument for <code>n1</code>, which is that the destructor would be
called later as the frame was left in the normal control flow).
</p>

<p>
I suggest that paragraph 4 of 17.14 <a href="https://wg21.link/support.runtime">[support.runtime]</a> should be replaced
with the following, or something that reads better but has the same effect:
</p>

<blockquote><p>
The function signature <code>longjmp(jmp_buf jbuf, int val)</code> has more
restricted behavior in this International Standard. A call to <code>longjmp</code>
has undefined behavior if any non-trivial destructors would be called were the
<code>longjmp</code> call replaced with a throw-expression whose nearest matching
handler were a (possibly imaginary) function-try-block on the function
containing the corresponding <code>setjmp</code> call.
</p></blockquote>

<p><i>[
2009-11-17 Moved to Tentatively NAD after 5 positive votes on c++std-lib. 
Rationale added below.
]</i></p>



<p id="res-1265"><b>Proposed resolution:</b></p>
<p>
Change 17.14 <a href="https://wg21.link/support.runtime">[support.runtime]</a>/4:
</p>

<blockquote><p>
The function signature <code>longjmp(jmp_buf jbuf, int val)</code> has more
restricted behavior in this International Standard. <del>A
<code>setjmp</code>/<code>longjmp</code> call pair has undefined behavior if replacing
the <code>setjmp</code> and <code>longjmp</code> by <code>catch</code> and <code>throw</code>
would invoke any non-trivial destructors for any automatic objects.</del>
<ins>A call to <code>longjmp</code> has undefined behavior if any non-trivial
destructors would be called were the <code>longjmp</code> call replaced with a
throw-expression whose nearest matching handler were a (possibly imaginary)
function-try-block on the function containing the corresponding <code>setjmp</code>
call.</ins>
</p></blockquote>


<p><b>Rationale:</b></p>
<p>
In the given example, it is clear that it is only <code>n2</code> and not
<code>n1</code> that is destroyed by the <code>longjmp</code>.
</p>
<p>
At this late stage in the standards process, we are focusing on issues that
impact users or implementers.  Trying to rewrite complex wording just for the
sake of improved clarity is likely to do more harm than good.
</p>





</body>
</html>
