<html>

<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Detailed I/O Error Reporting</title>
</head>

<body>

<p>Document number:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; N2769 = 08-0279<br>
Date:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%Y-%m-%d" startspan -->2008-09-17<!--webbot bot="Timestamp" endspan i-checksum="12609" --><br>
Project:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Programming Language C++, Library Working Group<br>
Reply-to:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
Beman Dawes &lt;bdawes at acm.org&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</p>
<h1>Detailed Reporting for Input/Output Library Errors (Revision 2)</h1>
<p><a href="#Introduction">Introduction</a><br>
<a href="#History">Revision History</a><br>
<a href="#Motivation">Motivation</a><br>
<a href="#Approach">Approach</a><br>
<a href="#TR2">C++0x or TR2?</a><br>
<a href="#Implementation-experience">Implementation experience</a><br>
<a href="#Acknowledgements">Acknowledgements</a><br>
<a href="#Proposed-wording">Proposed wording</a></p>
<h2><a name="Introduction">Introduction</a></h2>
<p>This paper proposes adding detailed error reporting, based on C++ standard 
library <i>System error support (19.4)</i>, to the C++ standard library's <i>
Input/output library (27)</i>.</p>
<h2>Revision <a name="History">History</a></h2>
<p>This proposal is a major revision of
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2655.html">
N2655</a>. At the request of the LWG, the proposed change is now limited to 
changing the base class of <code>
ios_base::failure</code> to <code>system_error</code>, and supplying the 
boilerplate to support that change.</p>
<p>The specification of&nbsp; <code>std::system_error</code> as a base class of
<code>std::basic_ios::failure</code> was originally proposed in
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2503.html">
N2503</a>, <i>Indicating iostream failures with <code>system_error</code></i>. </p>
<h2><a name="Motivation">Motivation</a></h2>
<p>Lack of detailed error reporting has long been a concern about the C++ I/O 
Streams library. For example, <i>The C++ Standard Library</i> by Nicolai 
Josuttis, complained in 1999:</p>
<blockquote>
<p>Unfortunately, the standard does not require that the exception object 
includes any information about the erroneous stream or the kind of error.</p>
</blockquote>
<p>The problem is particularly acute for failures to open a file. Such failures 
are extremely common and there are numerous possible reasons for failure, such 
as the file not being found, the permissions being wrong, and so forth. 
Diagnosing these failures without knowing the exact reason for failure is 
difficult, irritating, and time wasting.</p>
  <h2><a name="Impact-on-existing-code">Impact on existing code</a></h2>
  <p>The only known case where the proposal might break existing code is code that 
  depends on <code>ios_base::failure</code> being derived directly from <code>
  exception</code>. Library 
  clause 17.4.4.7 has always granted implementers permission to derive classes 
  from classes other than the specified base, so such code is already suspect.</p>
  <p>The proposal does break ABI compatibility in that the exception class derivation changes.</p>
  <h2>C++0x or <a name="TR2">TR2</a>?</h2>
  <p>Because of the ABI breakage, the LWG prefers to see this change in C++0x.</p>
  <h2><a name="Implementation-experience">Implementation experience</a></h2>
  <p>A C++03 proof-of-concept prototype of the proposal has been implemented by modifying the
  <a href="http://stdcxx.apache.org/">Apache C++ Standard Library</a>. No 
  difficulties were encountered and coding was straightforward.&nbsp; Virtually all changes 
  were on paths through the code that are only executed when a failure has 
  already been detected.</p>
  <h2><a name="Acknowledgements">Acknowledgements</a></h2>
  <p>Alisdair Meredith initiated the 
  original
  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2503.html">
  N2503</a> proposal and helped with the preparation of the current proposal.</p>
  <h2><a name="Proposed-wording">Proposed wording</a></h2>
  <p><i>To 27.4 Iostreams base classes [iostreams.base], Header <code>&lt;ios&gt;</code> 
  synopsis, add:</i></p>
<blockquote>
  <pre>enum class ioerrc { 
  stream=1
};

concept_map ErrorCodeEnum&lt;ioerrc&gt; {};

error_code make_error_code(ioerrc e);
error_condition make_error_condition(ioerrc e);

<i>storage-class-specifier</i> const error_category&amp; iostream_category;</pre>
  <p><i><span style="background-color: #C0C0C0">These additions are the 
  boilerplate required to create a new error category. See 19.4 of the WP.</span></i><br>
</p>
</blockquote>
<p><i>In a new sub-section, Error category object, add:</i></p>
<blockquote>
  <pre><i>storage-class-specifier</i> const error_category&amp; iostream_category;</pre>
  <blockquote>
  <p>The implementation shall initialize <tt>iostream_category</tt>. Its <i>
  storage-class-specifier</i> is permitted to be <tt>static</tt> or <tt>extern</tt>. 
  It is unspecified if initialization is static or dynamic (3.6.2 [basic.start.init]). 
  If initialization is dynamic, it shall occur before completion of the dynamic 
  initialization of the first translation unit dynamically initialized that 
  includes header <tt>&lt;system_error&gt;</tt>.</p>
  <p><i><span style="background-color: #C0C0C0">The exact form and wording for 
  describing error_category initialization is the topic of issue 890. The above 
  paragraph needs to be kept in sync with the final disposition of 890.</span></i></p>
  <p>The objects <code>default_error_condition</code> and <code>
  equivalent</code> virtual functions shall behave as specified for the class
  <code>error_category</code>. The objects <code>name</code> virtual function 
  shall return a pointer to the string <code>&quot;iostream&quot;</code>. </p>
  </blockquote>
</blockquote>
  <p><i>At a location to be determined, add:</i></p>
<blockquote>
  <p><code>error_code make_error_code(ioerrc e);</code></p>
  <blockquote>
    <p><i>Returns:</i> <code>error_code(static_cast&lt;int&gt;(e), io_category)</code>.</p>
  </blockquote>
  <p><code>error_condition make_error_condition(ioerrc e);</code></p>
  <blockquote>
    <p><i>Returns:</i> <code>error_condition(static_cast&lt;int&gt;(e), io_category)</code>.</p>
  </blockquote>
</blockquote>
<p><i>Change 27.4.2.1.1 Class ios_base::failure [ios::failure] as indicated: </i> </p>
<blockquote>
  <pre><code>namespace std {
  class ios_base::failure : public <font color="#FF0000"><del>exception</del></font><font color="#009A9A"><ins>system_error</ins></font> {
  public:
    explicit failure(const string&amp; msg<font color="#009A9A"><ins>, const error_code&amp; ec = ioerrc::</ins><u>stream</u></font>);
    explicit failure(const char* msg<font color="#009A9A"><ins>, const error_code&amp; ec = ioerrc::</ins></font><u><font color="#009A9A">stream</font></u>);
    virtual const char* what() const throw();
  };
}</code></pre>
  <p>The class <code>failure</code> defines the base class for the types of all objects 
  thrown as exceptions, by functions in the iostreams library, to report errors 
  detected during stream buffer operations. </p>
  <p><u><font color="#009A9A">When throwing <code>ios_base::failure</code> 
  exceptions, implementations are encouraged to provide values of ec that 
  identify the specific reason for the failure.&nbsp; [<i>Note</i> - Errors arising 
  from the operating system would typically be reported as <code>system_category</code> 
  errors with an error value of the error number reported by the operating 
  system. Errors arising from within the stream library would typically be 
  reported as&nbsp; <code>error_code(</code></font></u><font color="#009A9A"><code><ins>ioerrc::</ins><u>stream, 
  iostream_category)</u></code><u> <i>-- end note</i>].</u></font></p>
  <p><i><span style="background-color: #C0C0C0">The above wording provides only 
  normative encouragement for implementers to do the right thing, and thus 
  relies on market forces and the good intensions of implementers to produce 
  results useful to users. Anything stronger (such as changing &quot;are encouraged 
  to&quot; to &quot;shall&quot;) would require much additional specification and is beyond the 
  scope of what the </span><span style="background-color: #C0C0C0">LWG</span><span style="background-color: #C0C0C0"> 
  can realistically tackle for C++0x.</span></i></p>
  <p><code>explicit failure(const string&amp; msg<font color="#009A9A"><ins>, 
  const error_code&amp; ec = 
   
  ioerrc::</ins><u>stream</u></font>);</code> </p>
  <blockquote>
  <p><em>Effects:</em> Constructs an object of class <code>failure</code>. </p>
  <p><em>Postcondition:</em> <font color="#009A9A"><u> <code>code() == ec</code> and</u></font> <code>strcmp(what(), 
  msg.c_str()) == 0</code> </p>
  </blockquote>
  <p><code>explicit failure(const char* msg<font color="#009A9A"><ins>, const error_code&amp; ec = 
   
  ioerrc::</ins><u>stream</u></font>);</code> </p>
  <blockquote>
  <p><em>Effects:</em> Constructs an object of class <code>failure</code>. </p>
  <p><em>Postcondition:</em> <u><font color="#009A9A"> <code>code() == ec</code> and</font></u> <code>strcmp(what(), 
  msg ) == 0</code> </p>
  </blockquote>
</blockquote>
<hr>
  
</body>

</html>