differences.html 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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>Major differences - 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="../experimental/map.html"><img src="../images/prev.png" alt="Prev"></a>
  10. <a accesskey="u" href="../experimental.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="../experimental/status_result.html"><img src="../images/next.png" alt="Next"></a></div><div id="content">
  12. <div class="titlepage"><div><div><h1 style="clear: both">Major differences</h1></div></div></div>
  13. <p>The major design differences between <code>&lt;system_error&gt;</code> and proposed <code>&lt;system_error2&gt;</code> are
  14. as follows:</p>
  15. <ol>
  16. <li><p><code>experimental::status_code&lt;DomainType&gt;</code> can represent warnings
  17. and form-of-success codes as well as failure codes. <code>experimental::errored_status_code&lt;DomainType&gt;</code>
  18. is more similar to <code>std::error_code</code>, in that it can only represent failures
  19. (this is enforced by C++ 20 contract or runtime assertion check).</p></li>
  20. <li><p>The code&rsquo;s domain implementation defines the payload type to be transported around by
  21. <code>experimental::status_code&lt;DomainType&gt;</code>, rather than it being
  22. hardcoded to <code>int</code> as in <code>std::error_code</code>. The payload type can be anything
  23. you like, including non-trivially-copyable, move-only, complex etc types.</p>
  24. <p>This facility is extremely useful. Extra failure metadata such as stack
  25. backtraces can be returned, for example. You can absolutely vary the payload
  26. depending on whether <code>NDEBUG</code> or <code>_DEBUG</code> is defined, too.</p></li>
  27. <li><p>If your domain defines a payload type which is trivially copyable or
  28. move relocating<sup class="footnote-ref" id="fnref:1"><a href="#fn:1">1</a></sup>, it gains an implicit convertibility to a move-only
  29. <code>experimental::status_code&lt;erased&lt;T&gt;&gt;</code> where <code>T</code> is another
  30. trivially copyable or move relocating type. This permits global headers
  31. to use a single, common, type erased, status code type which is highly
  32. desirable for code bases of any complexity. However, unlike <code>std::error_code</code>,
  33. which fulfils the exact same role in <code>&lt;system_error&gt;</code> based code, the type
  34. erased payload can be bigger than the hardcoded <code>int</code> in <code>std::error_code</code>.</p>
  35. <p>This facility is also extremely useful, as extra failure metadata can be
  36. type erased, transported through code with no knowledge of such things,
  37. and the original type with failure metadata resurrected at the handling point.
  38. Indeed P1095 proposed <code>std::error</code> is a type alias to
  39. <code>experimental::status_code&lt;erased&lt;intptr_t&gt;&gt;</code>, and it can transport erased
  40. <code>std::exception_ptr</code> instances, POSIX error codes, and much more besides.</p></li>
  41. <li><p>Equality comparisons between status code&rsquo;s with non-identical domains are
  42. always <b><em>semantic</em></b> i.e. are they semantically equivalent, rather than exactly
  43. equal? This mirrors when you compare <code>std::error_code</code> to a <code>std::error_condition</code>,
  44. but as there is no equivalent for the latter in <code>&lt;system_error2&gt;</code>, this means
  45. that when you see the code:</p>
  46. <div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="k">if</span><span class="p">(</span><span class="n">code1</span> <span class="o">==</span> <span class="n">code2</span><span class="p">)</span> <span class="p">...</span>
  47. </code></pre></div>
  48. <p>&hellip; you can be highly confident that this is an inexact, semantic, match operation.
  49. The same code under <code>&lt;system_error&gt;</code> is highly ambiguous as to whether exact
  50. or inexact comparison is being performed (after all, all there is is &ldquo;<code>code1 == code2</code>&rdquo;,
  51. so it depends on the types of <code>code1</code> and <code>code2</code> which usually is not obvious).</p>
  52. <p>The ambiguity, and high cognitive load during auditing <code>&lt;system_error&gt;</code> code for correctness, has
  53. led to many surprising and unexpected failure handling bugs during the past
  54. decade in production C++.</p></li>
  55. <li><p><code>&lt;system_error2&gt;</code>, being a new design, has all-constexpr construction and
  56. destruction which avoids the need for static global variables, as <code>&lt;system_error&gt;</code>
  57. has. Each of those static global variables requires an atomic fence just in
  58. case it has not been initialised, thus every retrieval of an error category bloats
  59. code and inhibits optimisation, plus makes the use of custom error code categories
  60. in header-only libraries unreliable. Boost.System has replicated the all-constexpr
  61. construction and destruction from <code>&lt;system_error2&gt;</code>, and thus now has similar
  62. characteristics in this regard.</p></li>
  63. <li><p>Finally, this is a small but important difference. Under <code>&lt;system_error&gt;</code>,
  64. this extremely common use case is ambiguous:</p>
  65. <div class="highlight"><pre class="chroma"><code class="language-c++" data-lang="c++"><span class="k">if</span><span class="p">(</span><span class="n">ec</span><span class="p">)</span> <span class="p">...</span>
  66. </code></pre></div>
  67. <p>Does this code mean &ldquo;if there was an error?&rdquo;, or &ldquo;if the error code is set?&rdquo;,
  68. or &ldquo;is the error code non-zero?&rdquo;. The correct answer according to the standard is the last choice, but
  69. a quick survey of open source <code>&lt;system_error&gt;</code> based code on github quickly
  70. demonstrates there is widespread confusion regarding correct usage.</p>
  71. <p><code>&lt;system_error2&gt;</code> solves this by removing the boolean test entirely. One
  72. now writes <code>if(sc.success()) ...</code>, <code>if(sc.failure()) ...</code>, <code>if(sc.empty()) ...</code>
  73. and so on, thus eliminating ambiguity.</p></li>
  74. </ol>
  75. <div class="footnotes">
  76. <hr />
  77. <ol>
  78. <li id="fn:1"><a href="http://wg21.link/P1029">Move relocating is not in the standard, nor has been reviewed by WG21 yet</a>. It is defined to be a type whose move constructor <code>memcpy()</code>&rsquo;s the bits from source to destination, followed by <code>memcpy()</code> of the bits of a default constructed instance to source, and with a programmer-given guarantee that the destructor, when called on a default constructed instance, has no observable side effects. A surprising number of standard library types can meet this definition of move relocating, including <code>std::vector&lt;T&gt;</code>, <code>std::shared_ptr&lt;T&gt;</code>, and <code>std::exception_ptr</code>.
  79. <a class="footnote-return" href="#fnref:1"><sup>[return]</sup></a></li>
  80. </ol>
  81. </div>
  82. </div><p><small>Last revised: February 05, 2019 at 17:14:18 UTC</small></p>
  83. <hr>
  84. <div class="spirit-nav">
  85. <a accesskey="p" href="../experimental/map.html"><img src="../images/prev.png" alt="Prev"></a>
  86. <a accesskey="u" href="../experimental.html"><img src="../images/up.png" alt="Up"></a>
  87. <a accesskey="h" href="../index.html"><img src="../images/home.png" alt="Home"></a><a accesskey="n" href="../experimental/status_result.html"><img src="../images/next.png" alt="Next"></a></div></body>
  88. </html>