<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<title></title>
<style type="text/css">

/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.

See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/

/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
  border: 0 }

table.borderless td, table.borderless th {
  /* Override padding for "table.docutils td" with "! important".
     The right padding separates the table cells. */
  padding: 0 0.5em 0 0 ! important }

.first {
  /* Override more specific margin styles with "! important". */
  margin-top: 0 ! important }

.last, .with-subtitle {
  margin-bottom: 0 ! important }

.hidden {
  display: none }

a.toc-backref {
  text-decoration: none ;
  color: black }

blockquote.epigraph {
  margin: 2em 5em ; }

dl.docutils dd {
  margin-bottom: 0.5em }

/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
  font-weight: bold }
*/

div.abstract {
  margin: 2em 5em }

div.abstract p.topic-title {
  font-weight: bold ;
  text-align: center }

div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
  margin: 2em ;
  border: medium outset ;
  padding: 1em }

div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
  font-weight: bold ;
  font-family: sans-serif }

div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
  color: red ;
  font-weight: bold ;
  font-family: sans-serif }

/* Uncomment (and remove this text!) to get reduced vertical space in
   compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
  margin-bottom: 0.5em }

div.compound .compound-last, div.compound .compound-middle {
  margin-top: 0.5em }
*/

div.dedication {
  margin: 2em 5em ;
  text-align: center ;
  font-style: italic }

div.dedication p.topic-title {
  font-weight: bold ;
  font-style: normal }

div.figure {
  margin-left: 2em ;
  margin-right: 2em }

div.footer, div.header {
  clear: both;
  font-size: smaller }

div.line-block {
  display: block ;
  margin-top: 1em ;
  margin-bottom: 1em }

div.line-block div.line-block {
  margin-top: 0 ;
  margin-bottom: 0 ;
  margin-left: 1.5em }

div.sidebar {
  margin: 0 0 0.5em 1em ;
  border: medium outset ;
  padding: 1em ;
  background-color: #ffffee ;
  width: 40% ;
  float: right ;
  clear: right }

div.sidebar p.rubric {
  font-family: sans-serif ;
  font-size: medium }

div.system-messages {
  margin: 5em }

div.system-messages h1 {
  color: red }

div.system-message {
  border: medium outset ;
  padding: 1em }

div.system-message p.system-message-title {
  color: red ;
  font-weight: bold }

div.topic {
  margin: 2em }

h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
  margin-top: 0.4em }

h1.title {
  text-align: center }

h2.subtitle {
  text-align: center }

hr.docutils {
  width: 75% }

img.align-left {
  clear: left }

img.align-right {
  clear: right }

ol.simple, ul.simple {
  margin-bottom: 1em }

ol.arabic {
  list-style: decimal }

ol.loweralpha {
  list-style: lower-alpha }

ol.upperalpha {
  list-style: upper-alpha }

ol.lowerroman {
  list-style: lower-roman }

ol.upperroman {
  list-style: upper-roman }

p.attribution {
  text-align: right ;
  margin-left: 50% }

p.caption {
  font-style: italic }

p.credits {
  font-style: italic ;
  font-size: smaller }

p.label {
  white-space: nowrap }

p.rubric {
  font-weight: bold ;
  font-size: larger ;
  color: maroon ;
  text-align: center }

p.sidebar-title {
  font-family: sans-serif ;
  font-weight: bold ;
  font-size: larger }

p.sidebar-subtitle {
  font-family: sans-serif ;
  font-weight: bold }

p.topic-title {
  font-weight: bold }

pre.address {
  margin-bottom: 0 ;
  margin-top: 0 ;
  font-family: serif ;
  font-size: 100% }

pre.literal-block, pre.doctest-block {
  margin-left: 2em ;
  margin-right: 2em }

span.classifier {
  font-family: sans-serif ;
  font-style: oblique }

span.classifier-delimiter {
  font-family: sans-serif ;
  font-weight: bold }

span.interpreted {
  font-family: sans-serif }

span.option {
  white-space: nowrap }

span.pre {
  white-space: pre }

span.problematic {
  color: red }

span.section-subtitle {
  /* font-size relative to parent (h1..h6 element) */
  font-size: 80% }

table.citation {
  border-left: solid 1px gray;
  margin-left: 1px }

table.docinfo {
  margin: 2em 4em }

table.docutils {
  margin-top: 0.5em ;
  margin-bottom: 0.5em }

table.footnote {
  border-left: solid 1px black;
  margin-left: 1px }

table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
  padding-left: 0.5em ;
  padding-right: 0.5em ;
  vertical-align: top }

table.docutils th.field-name, table.docinfo th.docinfo-name {
  font-weight: bold ;
  text-align: left ;
  white-space: nowrap ;
  padding-left: 0 }

h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
  font-size: 100% }

ul.auto-toc {
  list-style-type: none }

</style>
</head>
<body>
<div class="document">


<div class="section" id="accessing-current-exception-during-unwinding">
<h1>Accessing current exception during unwinding</h1>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">Authors:</th><td class="field-body">Ville Voutilainen &lt;<a class="reference external" href="mailto:ville.voutilainen&#64;gmail.com">ville.voutilainen&#64;gmail.com</a>&gt;</td>
</tr>
<tr class="field"><th class="field-name">Number:</th><td class="field-body">N2952=09-0142</td>
</tr>
<tr class="field"><th class="field-name">Date:</th><td class="field-body">2009-09-21</td>
</tr>
</tbody>
</table>
<div class="section" id="abstract">
<h2>Abstract</h2>
<p>This paper proposes a facility for accessing exceptions during
stack unwinding, allowing rethrowing exceptions during unwind,
which facilitates eg. non-intrusive logging of exceptions.</p>
</div>
</div>
<div class="section" id="the-problem">
<h1>The Problem</h1>
<p>Currently, throw; ([except.throw]/p8) and current_exception() ([propagation]/p7)
can be used to access the &quot;currently handled exception&quot; ([except.handle]/p8);
practically this means that they can be used within catch blocks, but
not during stack unwinding. It's not possible to rethrow exceptions
during stack unwind, or get a pointer to the in-flight exception
with current_exception(). People often request such a feature, in order
to be able to log an exception in the destructor of a logger object.</p>
<div class="section" id="rudimentary-example-of-the-desired-facility">
<h2>Rudimentary example of the desired facility</h2>
<pre class="literal-block">
 struct logger
 {
   logger(const char* file, const char* line)
   {
     impl_-&gt;log_entry(file, line);
   }
   ~logger()
   {
     if (uncaught_exception()) {
       try {
         throw;
       } catch (foo&amp; e) {
         impl_-&gt;log_foo(e);
       } catch (bar&amp; e) {
         impl_-&gt;log_bar(e);
       } catch (...) {
         impl_-&gt;log_unknown(e);
       }
     }
     impl_-&gt;log_exit();
  }
  logger_impl* impl_;
};
</pre>
<p>The usage is roughly something like</p>
<pre class="literal-block">
void f()
{
  logger log(__FILE__, __LINE__);
  //whatever operations here that may throw
}
</pre>
<p>So the logger is a RAII object that should be able to
log function entry/exit, and preferably also any exceptions
occurring. Currently this sort of logger can't be written
because throw; can only be done within a catch block, and
current_exception() will return a null exception_ptr if
called outside a catch block.</p>
</div>
</div>
<div class="section" id="proposed-solution">
<h1>Proposed solution</h1>
<p>For the bare minimum, allowing throw; during unwind
would be enough. However, it's valuable to also allow
access to an exception_ptr returned by current_exception()
during unwind. Some examples follow:</p>
<pre class="literal-block">
~foo()
{
  if (uncaught_exception()) {
    try {
      throw; // ok, an exception is in-flight
    } catch (...) { // ok, the exception does not exit the destructor
    }
  }
}

~foo()
{
  throw; // this causes terminate(), a destructor
         // may not exit with an exception if unwind is
         // caused by an exception. Causes terminate() also
         // if there's no exception in-flight.
}

~foo()
{
  if (uncaught_exception()) {
    try {
      throw; // ok, an exception is in-flight
    } catch (foo_exception&amp;) {
    } // this may cause terminate() if the in-flight exception
      // is not of a type convertible to foo_exception&amp;
  }
}

void f()
{
  throw; // if invoked from a destructor during unwind, it is ok as long
         // as the destructor does not exit with an exception. Also ok
         // if invoked from a catch block.
}

void f()
{
  if (uncaught_exception()) {
    throw; // if invoked from a destructor during unwind, it is ok as long
           // as the destructor does not exit with an exception. In a catch
           // block, the exception is not uncaught and the condition
           // is false.
  }
}

void f()
{
  exception_ptr current = current_exception(); // will return non-null if
                                               // an exception is in-flight
  if (current) {
    throw; // if invoked from a destructor during unwind, it is ok as long
           // as the destructor does not exit with an exception. Also works
           // in a catch block.
  }
}

~foo()
{
  exception_ptr current = current_exception(); // will return non-null if
                                               // an exception is in-flight
  if (current) {
    try {
      throw; // ok, an exception is in-flight
    } catch (...) { // ok, the exception does not exit the destructor
    }
  }
}
</pre>
<p>So, to summarize,</p>
<ul class="simple">
<li>throw; is allowed both in a catch block and during unwinding</li>
<li>current_exception() will return non-null both in a catch
block and during unwinding</li>
<li>uncaught_exception() is left as is</li>
</ul>
<p>I don't propose specific drafting yet, the wording must be carefully
thought in order to fit into the existing standardese about exception
handling.</p>
<div class="section" id="additional-wishes">
<h2>Additional wishes</h2>
<p>In addition to accessing exceptions during unwind, people
have expressed desire to access a function return value
during unwind. I'd like to get EWG feedback for something
roughly like</p>
<pre class="literal-block">
exception_ptr current_return_value()
</pre>
<p>Where the return value would be wrapped in an exception_ptr
and could be rethrown and caught in order to deduce the type
of the return value. I don't think such an exception_ptr would
have a similar lifetime to the ones returned by current_exception(),
because I think it would be expensive to copy the return value
for storing after the return value has been received at the call
site. Nevertheless, I'd like to know what EWG thinks of such
a facility. Currently people try to hack this sort of facility
in assembler, which leads to non-portable code.</p>
</div>
</div>
</div>
</body>
</html>
