errno.html 5.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  3. <title>errno - Boost.Outcome documentation</title>
  4. <link rel="stylesheet" href="../css/boost.css" type="text/css">
  5. <meta name="generator" content="Hugo 0.52 with Boostdoc theme">
  6. <meta name="viewport" content="width=device-width,initial-scale=1.0"/>
  7. <link rel="icon" href="../images/favicon.ico" type="image/ico"/>
  8. <body><div class="spirit-nav">
  9. <a accesskey="p" href="../motivation/exceptions.html"><img src="../images/prev.png" alt="Prev"></a>
  10. <a accesskey="u" href="../motivation.html"><img src="../images/up.png" alt="Up"></a>
  11. <a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../motivation/error_codes.html"><img src="../images/next.png" alt="Next"></a></div><div id="content">
  12. <div class="titlepage"><div><div><h1 style="clear: both">errno</h1></div></div></div>
  13. <p>The idiom of returning, upon failure, a special value and storing an error code
  14. (an <code>int</code>) inside a global (or thread-local) object <code>errno</code> is inherited from C,
  15. and used in its Standard Library:</p>
  16. <div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="kt">int</span> <span class="nf">readValue</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span> <span class="n">filename</span><span class="p">)</span>
  17. <span class="p">{</span>
  18. <span class="n">FILE</span><span class="o">*</span> <span class="n">f</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span> <span class="s">&#34;r&#34;</span><span class="p">);</span>
  19. <span class="k">if</span> <span class="p">(</span><span class="n">f</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">)</span>
  20. <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// special value indicating failure
  21. </span><span class="c1"></span> <span class="c1">// keep errno value set by fopen()
  22. </span><span class="c1"></span>
  23. <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
  24. <span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="n">fscanf</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="s">&#34;%d&#34;</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">i</span><span class="p">);</span>
  25. <span class="k">if</span> <span class="p">(</span><span class="n">r</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">r</span> <span class="o">==</span> <span class="n">EOF</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// special values: i not read
  26. </span><span class="c1"></span> <span class="n">errno</span> <span class="o">=</span> <span class="n">ENODATA</span><span class="p">;</span> <span class="c1">// choose error value to return
  27. </span><span class="c1"></span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
  28. <span class="n">fclose</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
  29. <span class="n">errno</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// clear error info (success)
  30. </span><span class="c1"></span> <span class="k">return</span> <span class="n">i</span><span class="p">;</span>
  31. <span class="p">}</span>
  32. </code></pre></div>
  33. <p>One advantage (to some, and a disadvantage to others) of this technique is that it
  34. uses familiar control statements (<code>if</code> and <code>return</code>) to indicate all execution
  35. paths that handle failures. When we read this code we know when and under what
  36. conditions it can exit without producing the expected result.</p>
  37. <h3 id="downsides">Downsides</h3>
  38. <p>Because on failure, as well as success, we write into a global (or thread-local)
  39. object, our functions are not <em>pure</em>: they have <em>side effects</em>. This means many
  40. useful compiler optimizations (like common subexpression elimination) cannot be
  41. applied. This shows that it is not only C++ that chooses suboptimal solutions
  42. for reporting failures.</p>
  43. <p>Whatever type we return, we always need a special value to spare, which is
  44. sometimes troublesome. In the above example, if the successfully read value of
  45. <code>i</code> is <code>0</code>, and we return it, our callers will think it is a failure even though
  46. it is not.</p>
  47. <p>Error propagation using <code>if</code> statements and early <code>return</code>s is manual. We can easily
  48. forget to check for the failure, and incorrectly let the subsequent operations
  49. execute, potentially causing damage to the program state.</p>
  50. <p>Upon nearly each function call layer we may have to change error code value
  51. so that it reflects the error condition adequate to the current layer. If we
  52. do so, the original error code is gone.</p>
  53. </div><p><small>Last revised: January 16, 2019 at 01:05:39 &#43;0100</small></p>
  54. <hr>
  55. <div class="spirit-nav">
  56. <a accesskey="p" href="../motivation/exceptions.html"><img src="../images/prev.png" alt="Prev"></a>
  57. <a accesskey="u" href="../motivation.html"><img src="../images/up.png" alt="Up"></a>
  58. <a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../motivation/error_codes.html"><img src="../images/next.png" alt="Next"></a></div></body>
  59. </html>