• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
8<link rel="icon" href="../images/favicon.ico" type="image/ico"/>
9<body><div class="spirit-nav">
10<a accesskey="p" href="../motivation/exceptions.html"><img src="../images/prev.png" alt="Prev"></a>
11    <a accesskey="u" href="../motivation.html"><img src="../images/up.png" alt="Up"></a>
12    <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">
13  <div class="titlepage"><div><div><h1 style="clear: both">errno</h1></div></div></div>
14
15
16<p>The idiom of returning, upon failure, a special value and storing an error code
17(an <code>int</code>) inside a global (or thread-local) object <code>errno</code> is inherited from C,
18and used in its Standard Library:</p>
19<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>
20<span class="p">{</span>
21  <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>
22  <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>
23    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// special value indicating failure
24</span><span class="c1"></span>              <span class="c1">// keep errno value set by fopen()
25</span><span class="c1"></span>
26  <span class="kt">int</span> <span class="n">i</span><span class="p">;</span>
27  <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>
28  <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
29</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
30</span><span class="c1"></span>    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
31
32  <span class="n">fclose</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
33  <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)
34</span><span class="c1"></span>  <span class="k">return</span> <span class="n">i</span><span class="p">;</span>
35<span class="p">}</span>
36</code></pre></div>
37<p>One advantage (to some, and a disadvantage to others) of this technique is that it
38uses familiar control statements (<code>if</code> and <code>return</code>) to indicate all execution
39paths that handle failures. When we read this code we know when and under what
40conditions it can exit without producing the expected result.</p>
41
42<h3 id="downsides">Downsides</h3>
43
44<p>Because on failure, as well as success, we write into a global (or thread-local)
45object, our functions are not <em>pure</em>: they have <em>side effects</em>. This means many
46useful compiler optimizations (like common subexpression elimination) cannot be
47applied. This shows that it is not only C++ that chooses suboptimal solutions
48for reporting failures.</p>
49
50<p>Whatever type we return, we always need a special value to spare, which is
51sometimes troublesome. In the above example, if the successfully read value of
52<code>i</code> is <code>0</code>, and we return it, our callers will think it is a failure even though
53it is not.</p>
54
55<p>Error propagation using <code>if</code> statements and early <code>return</code>s is manual. We can easily
56forget to check for the failure, and incorrectly let the subsequent operations
57execute, potentially causing damage to the program state.</p>
58
59<p>Upon nearly each function call layer we may have to change error code value
60so that it reflects the error condition adequate to the current layer. If we
61do so, the original error code is gone.</p>
62
63
64        </div><p><small>Last revised: January 16, 2019 at 01:05:39 &#43;0100</small></p>
65<hr>
66<div class="spirit-nav">
67<a accesskey="p" href="../motivation/exceptions.html"><img src="../images/prev.png" alt="Prev"></a>
68    <a accesskey="u" href="../motivation.html"><img src="../images/up.png" alt="Up"></a>
69    <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>
70</html>
71