Topic: Support for exception-less error handling


Author: Igor Baidiuk <target.san@gmail.com>
Date: Thu, 29 Jun 2017 04:39:37 -0700 (PDT)
Raw View
------=_Part_3458_719819748.1498736377359
Content-Type: multipart/alternative;
 boundary="----=_Part_3459_664505877.1498736377359"

------=_Part_3459_664505877.1498736377359
Content-Type: text/plain; charset="UTF-8"

There's a rather strange situation with error handling in C++, at least to
me.

   - Exception-based error handling is de-facto recommended way. It's
   relatively ergonomic, allows to pass arbitrary info about error, gives ways
   to filter exceptions by type. As a price, exceptions have runtime penalty,
   require compiler support and are not reflected in function signatures -
   checked exceptions were deprecated long ago, if I'm not mistaken. Also,
   they're prohibited in some coding conventions (loike Google's) and
   no-livers in lowlevel development.
   - Exception-less error handling is based mostly on error codes. It works
   everywhere, requires no special runtime support, and error type (especially
   if it's a proper enum) is reflected in function signature - which grants
   more compiler help. As a downside, the code which uses error statuses often
   contains much boilerplate ("if (there-is-an-error) { handle-error;} "), and
   error statuses are usually easy to omit and not handle.

What if we had ergonomics for error codes almost equal to exceptions?


The issues with error code easy to not process and not carry any additional
info are relatively easy to solve. There was a proposal to add
std::expected type, which is a C++ implementation of Either/Result
algebraic data type well known in FP world. Such a type would require
explicit unpacking to get value and explicit checking if there's an error.


The issue with status checking boilerplate is more complex though. In fact
it requires that an expression is allowed to both declare expression-local
variable and have return statement:

   1. The result of function call is assigned to some temporary
   2. The temporary is checked if it contains error
   3. If there's an error, error-object is returned early from function
   4. If there's an actual result, that result becomes result of expression

The main problem is that C++ has strict distinction between statements and
expressions, and doesn't allow to mix them. Based on this, we need to
either allow 'if' statement to be expression in some cases, or allow
declaration statement and return statement to be used in ternary operator:


auto result = if (auto&& __tmp__ = func_returning_result(), __tmp__.
is_result())
    { std::forward<decltype(func_returning_result())>(__tmp__).get_result();
}
    else { return std::forward<decltype(func_returning_result())>(__tmp__).get_error();
};

or, with ternary operator:


auto result = (auto&& __tmp__ = func_returning_result(), __tmp__.is_result()
    ? std::forward<decltype(func_returning_result())>(__tmp__).get_result()
    : return std::forward<decltype(func_returning_result()
)>(__tmp__).get_error());

Of course, such boilerplate can be hidden behind macro - but
"result-or-return expression" doesn't seem to be valid construct in current
C++.


Thoughts on this?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/b5a114a6-dbc3-45ff-b45b-b46cdcc51a03%40isocpp.org.

------=_Part_3459_664505877.1498736377359
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">There&#39;s a rather strange situation with error handling=
 in C++, at least to me.<br><ul><li>Exception-based error handling is de-fa=
cto recommended way. It&#39;s relatively ergonomic, allows to pass arbitrar=
y info about error, gives ways to filter exceptions by type. As a price, ex=
ceptions have runtime penalty, require compiler support and are not reflect=
ed in function signatures - checked exceptions were deprecated long ago, if=
 I&#39;m not mistaken. Also, they&#39;re prohibited in some coding conventi=
ons (loike Google&#39;s) and no-livers in lowlevel development.<br></li><li=
>Exception-less error handling is based mostly on error codes. It works eve=
rywhere, requires no special runtime support, and error type (especially if=
 it&#39;s a proper enum) is reflected in function signature - which grants =
more compiler help. As a downside, the code which uses error statuses often=
 contains much boilerplate (&quot;if (there-is-an-error) { handle-error;} &=
quot;), and error statuses are usually easy to omit and not handle.</li></u=
l><p>What if we had ergonomics for error codes almost equal to exceptions?<=
/p><p><br></p><p>The issues with error code easy to not process and not car=
ry any additional info are relatively easy to solve. There was a proposal t=
o add std::expected type, which is a C++ implementation of Either/Result al=
gebraic data type well known in FP world. Such a type would require explici=
t unpacking to get value and explicit checking if there&#39;s an error.<br>=
</p><p><br></p><p>The issue with status checking boilerplate is more comple=
x though. In fact it requires that an expression is allowed to both declare=
 expression-local variable and have return statement:</p><ol><li>The result=
 of function call is assigned to some temporary</li><li>The temporary is ch=
ecked if it contains error</li><li>If there&#39;s an error, error-object is=
 returned early from function</li><li>If there&#39;s an actual result, that=
 result becomes result of expression</li></ol><p>The main problem is that C=
++ has strict distinction between statements and expressions, and doesn&#39=
;t allow to mix them. Based on this, we need to either allow &#39;if&#39; s=
tatement to be expression in some cases, or allow declaration statement and=
 return statement to be used in ternary operator:</p><p><br></p><p></p><div=
 style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187,=
 187); border-style: solid; border-width: 1px; overflow-wrap: break-word;" =
class=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettypr=
int"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> result </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">&amp;&amp;</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> __tmp__ </span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> func_returning_result</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(),</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> __tmp__</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">is_re=
sult</span><span style=3D"color: #660;" class=3D"styled-by-prettify">())<br=
></span><span style=3D"color: #000;" class=3D"styled-by-prettify"></span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=C2=A0=C2=A0=C2=A0 =
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">forward</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">decltype</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><code class=3D"prettyprint=
"><span style=3D"color: #000;" class=3D"styled-by-prettify">func_returning_=
result</span><span style=3D"color: #660;" class=3D"styled-by-prettify">()</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">)&gt;(__tmp_=
_).get_result(); }<br>=C2=A0=C2=A0=C2=A0 else { return </span></code><code =
class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prett=
ify">std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">forward</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #008;" class=3D"styled-by-prettify">decltype</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">(</span><code class=
=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">=
func_returning_result</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">()</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">)&gt;(__tmp__).get_error(); };</span></code></code><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"></span></div></code></div><br>or, with=
 ternary operator:<p></p><p><br></p><p></p><div style=3D"background-color: =
rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; =
border-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code =
class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #=
606;" class=3D"styled-by-prettify">auto result =3D (</span><span style=3D"c=
olor: #606;" class=3D"styled-by-prettify"><code class=3D"prettyprint"><span=
 style=3D"color: #000;" class=3D"styled-by-prettify"></span><span style=3D"=
color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color:=
 #660;" class=3D"styled-by-prettify">&amp;&amp;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> __tmp__ </span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> func_returning_result</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(),</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> __tmp__</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">is_result</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">()<br></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=C2=A0=C2=A0=C2=A0 ?</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">forward</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify">dec=
ltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled=
-by-prettify">func_returning_result</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">()</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">)&gt;(__tmp__).get_result()<br>=C2=A0=C2=A0=C2=A0 : return=
 </span></code><code class=3D"prettyprint"><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">std</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">forward</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">&lt;</span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">decltype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
(</span><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">func_returning_result</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">()</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">)&gt;(__tmp__).get_error());</span></code></code></=
code></span></div></code></div><br>Of course, such boilerplate can be hidde=
n behind macro - but &quot;result-or-return expression&quot; doesn&#39;t se=
em to be valid construct in current C++.<p></p><p><br></p><p>Thoughts on th=
is?<br></p><br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/b5a114a6-dbc3-45ff-b45b-b46cdcc51a03%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/b5a114a6-dbc3-45ff-b45b-b46cdcc51a03=
%40isocpp.org</a>.<br />

------=_Part_3459_664505877.1498736377359--

------=_Part_3458_719819748.1498736377359--

.


Author: Bengt Gustafsson <bengt.gustafsson@beamways.com>
Date: Mon, 3 Jul 2017 13:21:13 -0700 (PDT)
Raw View
------=_Part_1990_2069585304.1499113273961
Content-Type: multipart/alternative;
 boundary="----=_Part_1991_1115211792.1499113273961"

------=_Part_1991_1115211792.1499113273961
Content-Type: text/plain; charset="UTF-8"

I would doubt that the runtime overhead of exceptions is worse than that of
checking return values and continue returning out the call stack.
Especially in the no-error case it should be more efficient as those ifs
have potentially large runtime penalty regardless of if the jump
instruction is taken or not, while the exception unwinding code is
typically very asymmetric with a minimized runtime cost for the non-throw
case.

So before suggesting another mechanism that simplifies writing code based
on error returns I would suggest actually measuring the performance in the
throwing and non-throwing case compared to a return value/if-based
solution. This article is not totally clear but casts serious doubts about
any speed gain from avoiding exceptions:

https://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow

Unfortunately (or fortunately as it is so old) the TS report linked to does
not show numbers for exception handling. Maybe someone else can point to a
paper detailing the performance for the different approaches?


Den torsdag 29 juni 2017 kl. 13:39:37 UTC+2 skrev Igor Baidiuk:
>
> There's a rather strange situation with error handling in C++, at least to
> me.
>
>    - Exception-based error handling is de-facto recommended way. It's
>    relatively ergonomic, allows to pass arbitrary info about error, gives ways
>    to filter exceptions by type. As a price, exceptions have runtime penalty,
>    require compiler support and are not reflected in function signatures -
>    checked exceptions were deprecated long ago, if I'm not mistaken. Also,
>    they're prohibited in some coding conventions (loike Google's) and
>    no-livers in lowlevel development.
>    - Exception-less error handling is based mostly on error codes. It
>    works everywhere, requires no special runtime support, and error type
>    (especially if it's a proper enum) is reflected in function signature -
>    which grants more compiler help. As a downside, the code which uses error
>    statuses often contains much boilerplate ("if (there-is-an-error) {
>    handle-error;} "), and error statuses are usually easy to omit and not
>    handle.
>
> What if we had ergonomics for error codes almost equal to exceptions?
>
>
> The issues with error code easy to not process and not carry any
> additional info are relatively easy to solve. There was a proposal to add
> std::expected type, which is a C++ implementation of Either/Result
> algebraic data type well known in FP world. Such a type would require
> explicit unpacking to get value and explicit checking if there's an error.
>
>
> The issue with status checking boilerplate is more complex though. In fact
> it requires that an expression is allowed to both declare expression-local
> variable and have return statement:
>
>    1. The result of function call is assigned to some temporary
>    2. The temporary is checked if it contains error
>    3. If there's an error, error-object is returned early from function
>    4. If there's an actual result, that result becomes result of
>    expression
>
> The main problem is that C++ has strict distinction between statements and
> expressions, and doesn't allow to mix them. Based on this, we need to
> either allow 'if' statement to be expression in some cases, or allow
> declaration statement and return statement to be used in ternary operator:
>
>
> auto result = if (auto&& __tmp__ = func_returning_result(), __tmp__.
> is_result())
>     { std::forward<decltype(func_returning_result())>(__tmp__).get_result();
> }
>     else { return std::forward<decltype(func_returning_result())>(__tmp__).get_error();
> };
>
> or, with ternary operator:
>
>
> auto result = (auto&& __tmp__ = func_returning_result(), __tmp__.is_result
> ()
>     ? std::forward<decltype(func_returning_result()
> )>(__tmp__).get_result()
>     : return std::forward<decltype(func_returning_result()
> )>(__tmp__).get_error());
>
> Of course, such boilerplate can be hidden behind macro - but
> "result-or-return expression" doesn't seem to be valid construct in current
> C++.
>
>
> Thoughts on this?
>
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6856d8da-734e-44c9-b45b-890f3142f83b%40isocpp.org.

------=_Part_1991_1115211792.1499113273961
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I would doubt that the runtime overhead of exceptions is w=
orse than that of checking return values and continue returning out the cal=
l stack. Especially in the no-error case it should be more efficient as tho=
se ifs have potentially large runtime penalty regardless of if the jump ins=
truction is taken or not, while the exception unwinding code is typically v=
ery asymmetric with a minimized runtime cost for the non-throw case.<div><b=
r></div><div>So before suggesting another mechanism that simplifies writing=
 code based on error returns I would suggest actually measuring the perform=
ance in the throwing and non-throwing case compared to a return value/if-ba=
sed solution. This article is not totally clear but casts serious doubts ab=
out any speed gain from avoiding exceptions:</div><div><br></div><div>https=
://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow</di=
v><div><br></div><div>Unfortunately (or fortunately as it is so old) the TS=
 report linked to does not show numbers for exception handling. Maybe someo=
ne else can point to a paper detailing the performance for the different ap=
proaches?<br><div><br><br>Den torsdag 29 juni 2017 kl. 13:39:37 UTC+2 skrev=
 Igor Baidiuk:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"=
>There&#39;s a rather strange situation with error handling in C++, at leas=
t to me.<br><ul><li>Exception-based error handling is de-facto recommended =
way. It&#39;s relatively ergonomic, allows to pass arbitrary info about err=
or, gives ways to filter exceptions by type. As a price, exceptions have ru=
ntime penalty, require compiler support and are not reflected in function s=
ignatures - checked exceptions were deprecated long ago, if I&#39;m not mis=
taken. Also, they&#39;re prohibited in some coding conventions (loike Googl=
e&#39;s) and no-livers in lowlevel development.<br></li><li>Exception-less =
error handling is based mostly on error codes. It works everywhere, require=
s no special runtime support, and error type (especially if it&#39;s a prop=
er enum) is reflected in function signature - which grants more compiler he=
lp. As a downside, the code which uses error statuses often contains much b=
oilerplate (&quot;if (there-is-an-error) { handle-error;} &quot;), and erro=
r statuses are usually easy to omit and not handle.</li></ul><p>What if we =
had ergonomics for error codes almost equal to exceptions?</p><p><br></p><p=
>The issues with error code easy to not process and not carry any additiona=
l info are relatively easy to solve. There was a proposal to add std::expec=
ted type, which is a C++ implementation of Either/Result algebraic data typ=
e well known in FP world. Such a type would require explicit unpacking to g=
et value and explicit checking if there&#39;s an error.<br></p><p><br></p><=
p>The issue with status checking boilerplate is more complex though. In fac=
t it requires that an expression is allowed to both declare expression-loca=
l variable and have return statement:</p><ol><li>The result of function cal=
l is assigned to some temporary</li><li>The temporary is checked if it cont=
ains error</li><li>If there&#39;s an error, error-object is returned early =
from function</li><li>If there&#39;s an actual result, that result becomes =
result of expression</li></ol><p>The main problem is that C++ has strict di=
stinction between statements and expressions, and doesn&#39;t allow to mix =
them. Based on this, we need to either allow &#39;if&#39; statement to be e=
xpression in some cases, or allow declaration statement and return statemen=
t to be used in ternary operator:</p><p><br></p><p></p><div style=3D"backgr=
ound-color:rgb(250,250,250);border-color:rgb(187,187,187);border-style:soli=
d;border-width:1px"><code><div><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> result </span><span style=3D"color:#660">=3D</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#008">if</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">(</span><span style=
=3D"color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span><spa=
n style=3D"color:#000"> __tmp__ </span><span style=3D"color:#660">=3D</span=
><span style=3D"color:#000"> func_returning_result</span><span style=3D"col=
or:#660">(),</span><span style=3D"color:#000"> __tmp__</span><span style=3D=
"color:#660">.</span><span style=3D"color:#000">is_result</span><span style=
=3D"color:#660">())<br></span><span style=3D"color:#000"></span><span style=
=3D"color:#660">=C2=A0=C2=A0=C2=A0 {</span><span style=3D"color:#000"> std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">forwar=
d</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">de=
cltype</span><span style=3D"color:#660">(</span><code><span style=3D"color:=
#000">func_<wbr>returning_result</span><span style=3D"color:#660">()</span>=
<span style=3D"color:#660">)&gt;(__tmp__).<wbr>get_result(); }<br>=C2=A0=C2=
=A0=C2=A0 else { return </span></code><code><span style=3D"color:#000">std<=
/span><span style=3D"color:#660">::</span><span style=3D"color:#000">forwar=
d</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">de=
cltype</span><span style=3D"color:#660">(</span><code><span style=3D"color:=
#000">func_<wbr>returning_result</span><span style=3D"color:#660">()</span>=
<span style=3D"color:#660">)&gt;(__tmp__).<wbr>get_error(); };</span></code=
></code><span style=3D"color:#000"></span></div></code></div><br>or, with t=
ernary operator:<p></p><p><br></p><p></p><div style=3D"background-color:rgb=
(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-width=
:1px"><code><div><span style=3D"color:#606">auto result =3D (</span><span s=
tyle=3D"color:#606"><code><span style=3D"color:#000"></span><span style=3D"=
color:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span><span st=
yle=3D"color:#000"> __tmp__ </span><span style=3D"color:#660">=3D</span><sp=
an style=3D"color:#000"> func_returning_result</span><span style=3D"color:#=
660">(),</span><span style=3D"color:#000"> __tmp__</span><span style=3D"col=
or:#660">.</span><span style=3D"color:#000">is_result</span><span style=3D"=
color:#660">()<br></span><span style=3D"color:#000"></span><span style=3D"c=
olor:#660">=C2=A0=C2=A0=C2=A0 ?</span><span style=3D"color:#000"> std</span=
><span style=3D"color:#660">::</span><span style=3D"color:#000">forward</sp=
an><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltyp=
e</span><span style=3D"color:#660">(</span><code><span style=3D"color:#000"=
>func_<wbr>returning_result</span><span style=3D"color:#660">()</span><span=
 style=3D"color:#660">)&gt;(__tmp__).<wbr>get_result()<br>=C2=A0=C2=A0=C2=
=A0 : return </span></code><code><span style=3D"color:#000">std</span><span=
 style=3D"color:#660">::</span><span style=3D"color:#000">forward</span><sp=
an style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype</spa=
n><span style=3D"color:#660">(</span><code><span style=3D"color:#000">func_=
<wbr>returning_result</span><span style=3D"color:#660">()</span><span style=
=3D"color:#660">)&gt;(__tmp__).<wbr>get_error());</span></code></code></cod=
e></span></div></code></div><br>Of course, such boilerplate can be hidden b=
ehind macro - but &quot;result-or-return expression&quot; doesn&#39;t seem =
to be valid construct in current C++.<p></p><p><br></p><p>Thoughts on this?=
<br></p><br></div></blockquote></div></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/6856d8da-734e-44c9-b45b-890f3142f83b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6856d8da-734e-44c9-b45b-890f3142f83b=
%40isocpp.org</a>.<br />

------=_Part_1991_1115211792.1499113273961--

------=_Part_1990_2069585304.1499113273961--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 3 Jul 2017 13:42:31 -0700 (PDT)
Raw View
------=_Part_2027_224609003.1499114551383
Content-Type: multipart/alternative;
 boundary="----=_Part_2028_452221702.1499114551383"

------=_Part_2028_452221702.1499114551383
Content-Type: text/plain; charset="UTF-8"

On Monday, July 3, 2017 at 4:21:14 PM UTC-4, Bengt Gustafsson wrote:
>
> I would doubt that the runtime overhead of exceptions is worse than that
> of checking return values and continue returning out the call stack.
> Especially in the no-error case it should be more efficient as those ifs
> have potentially large runtime penalty regardless of if the jump
> instruction is taken or not, while the exception unwinding code is
> typically very asymmetric with a minimized runtime cost for the non-throw
> case.
>
> So before suggesting another mechanism that simplifies writing code based
> on error returns I would suggest actually measuring the performance in the
> throwing and non-throwing case compared to a return value/if-based
> solution. This article is not totally clear but casts serious doubts about
> any speed gain from avoiding exceptions:
>
>
> https://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow
>
> Unfortunately (or fortunately as it is so old) the TS report linked to
> does not show numbers for exception handling. Maybe someone else can point
> to a paper detailing the performance for the different approaches?
>

You should really look at the SG14 forum and their various papers. They've
made measurements, looking at both the cost of the non-exception case and
the cost of the exceptional case.

Furthermore, there are different types of users of C++. For some, having a
*consistent* cost is more important than being faster most of the time but
really slow if something exceptional happens. And consistency of
performance can matter more in specific places than others.

Overall, I think a pretty decent case has been made that having a
functional alternative to exceptions, whether in the language or the
library, would be a good thing. The most pernicious case is the difficulty
of signaling errors from constructors; such a thing fundamentally requires
a language-level solution (or to write constructors that can't fail).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/694163cb-b551-425b-9f08-b229ca487859%40isocpp.org.

------=_Part_2028_452221702.1499114551383
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, July 3, 2017 at 4:21:14 PM UTC-4, Bengt Gustafs=
son wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">I w=
ould doubt that the runtime overhead of exceptions is worse than that of ch=
ecking return values and continue returning out the call stack. Especially =
in the no-error case it should be more efficient as those ifs have potentia=
lly large runtime penalty regardless of if the jump instruction is taken or=
 not, while the exception unwinding code is typically very asymmetric with =
a minimized runtime cost for the non-throw case.<div><br></div><div>So befo=
re suggesting another mechanism that simplifies writing code based on error=
 returns I would suggest actually measuring the performance in the throwing=
 and non-throwing case compared to a return value/if-based solution. This a=
rticle is not totally clear but casts serious doubts about any speed gain f=
rom avoiding exceptions:</div><div><br></div><div><a href=3D"https://stacko=
verflow.com/questions/13835817/are-exceptions-in-c-really-slow" target=3D"_=
blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.=
com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F13835817%2Fare-e=
xceptions-in-c-really-slow\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGxQJSKjI=
smIsPOL0HqtDJdPmQ-DQ&#39;;return true;" onclick=3D"this.href=3D&#39;https:/=
/www.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F1383=
5817%2Fare-exceptions-in-c-really-slow\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAF=
QjCNGxQJSKjIsmIsPOL0HqtDJdPmQ-DQ&#39;;return true;">https://stackoverflow.c=
om/<wbr>questions/13835817/are-<wbr>exceptions-in-c-really-slow</a></div><d=
iv><br></div><div>Unfortunately (or fortunately as it is so old) the TS rep=
ort linked to does not show numbers for exception handling. Maybe someone e=
lse can point to a paper detailing the performance for the different approa=
ches?<br></div></div></blockquote><div><br>You should really look at the SG=
14 forum and their various papers. They&#39;ve made measurements, looking a=
t both the cost of the non-exception case and the cost of the exceptional c=
ase.<br><br>Furthermore, there are different types of users of C++. For som=
e, having a <i>consistent</i> cost is more important than being faster most=
 of the time but really slow if something exceptional happens. And consiste=
ncy of performance can matter more in specific places than others.<br><br>O=
verall, I think a pretty decent case has been made that having a functional=
 alternative to exceptions, whether in the language or the library, would b=
e a good thing. The most pernicious case is the difficulty of signaling err=
ors from constructors; such a thing fundamentally requires a language-level=
 solution (or to write constructors that can&#39;t fail).</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/694163cb-b551-425b-9f08-b229ca487859%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/694163cb-b551-425b-9f08-b229ca487859=
%40isocpp.org</a>.<br />

------=_Part_2028_452221702.1499114551383--

------=_Part_2027_224609003.1499114551383--

.


Author: Brittany Friedman <fourthgeek@gmail.com>
Date: Mon, 3 Jul 2017 15:44:35 -0500
Raw View
--f403045e6c4abf5a5305536fd507
Content-Type: text/plain; charset="UTF-8"

On Mon, Jul 3, 2017 at 3:21 PM, Bengt Gustafsson <
bengt.gustafsson@beamways.com> wrote:

> I would doubt that the runtime overhead of exceptions is worse than that
> of checking return values and continue returning out the call stack.
> Especially in the no-error case it should be more efficient as those ifs
> have potentially large runtime penalty regardless of if the jump
> instruction is taken or not, while the exception unwinding code is
> typically very asymmetric with a minimized runtime cost for the non-throw
> case.
>
> So before suggesting another mechanism that simplifies writing code based
> on error returns I would suggest actually measuring the performance in the
> throwing and non-throwing case compared to a return value/if-based
> solution. This article is not totally clear but casts serious doubts about
> any speed gain from avoiding exceptions:
>
> https://stackoverflow.com/questions/13835817/are-
> exceptions-in-c-really-slow
>
> Unfortunately (or fortunately as it is so old) the TS report linked to
> does not show numbers for exception handling. Maybe someone else can point
> to a paper detailing the performance for the different approaches?
>
>
There are plenty of reasons to use error codes or error-code-like-entities
that are not motivated solely by performance considerations.

Some users find error codes easier to audit and work with (no hidden
control flow).
Some users are on platforms that recommend against or forbid the use of
exception handling. The platform vendor in question does not provide a
high-quality exception handling mechanism.
Some users don't want to pay for the *memory* overhead of the so-called
"""""""""zero cost""""""""" (there are not enough scare-quotes in the
world) mechanism.
Exceptions do not compose well (see the now defunct exception_list)
If we presume that exceptions can in *some* cases be slower, then if
"errors" are very common or if you require *predictable* performance
characteristics, exceptions may be unacceptable.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeStrnKpi-vxcHk1k4zzbkGaJsYOMDbkfZNMVvCtswAogQ%40mail.gmail.com.

--f403045e6c4abf5a5305536fd507
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Mon, Jul 3, 2017 at 3:21 PM, Bengt Gustafsson <span dir=3D"ltr">&lt;=
<a href=3D"mailto:bengt.gustafsson@beamways.com" target=3D"_blank">bengt.gu=
stafsson@beamways.com</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,2=
04);padding-left:1ex"><div dir=3D"ltr">I would doubt that the runtime overh=
ead of exceptions is worse than that of checking return values and continue=
 returning out the call stack. Especially in the no-error case it should be=
 more efficient as those ifs have potentially large runtime penalty regardl=
ess of if the jump instruction is taken or not, while the exception unwindi=
ng code is typically very asymmetric with a minimized runtime cost for the =
non-throw case.<div><br></div><div>So before suggesting another mechanism t=
hat simplifies writing code based on error returns I would suggest actually=
 measuring the performance in the throwing and non-throwing case compared t=
o a return value/if-based solution. This article is not totally clear but c=
asts serious doubts about any speed gain from avoiding exceptions:</div><di=
v><br></div><div><a href=3D"https://stackoverflow.com/questions/13835817/ar=
e-exceptions-in-c-really-slow" target=3D"_blank">https://stackoverflow.com/=
<wbr>questions/13835817/are-<wbr>exceptions-in-c-really-slow</a></div><div>=
<br></div><div>Unfortunately (or fortunately as it is so old) the TS report=
 linked to does not show numbers for exception handling. Maybe someone else=
 can point to a paper detailing the performance for the different approache=
s?<div><div class=3D"gmail-h5"><div><br></div></div></div></div></div></blo=
ckquote><div><br></div><div>There are plenty of reasons to use error codes =
or error-code-like-entities that are not motivated solely by performance co=
nsiderations.</div><div><br></div><div>Some users find error codes easier t=
o audit and work with (no hidden control flow).</div><div>Some users are on=
 platforms that recommend against or forbid the use of exception handling. =
The platform vendor in question does not provide a high-quality exception h=
andling mechanism.</div><div>Some users don&#39;t want to pay for the *memo=
ry* overhead of the so-called &quot;&quot;&quot;&quot;&quot;&quot;&quot;&qu=
ot;&quot;zero cost&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;=C2=
=A0(there are not enough scare-quotes in the world) mechanism.</div><div>Ex=
ceptions do not compose well (see the now defunct exception_list)</div><div=
>If we presume that exceptions can in *some* cases be slower, then if &quot=
;errors&quot; are very common or if you require *predictable* performance c=
haracteristics, exceptions may be unacceptable.</div><div><br></div></div><=
/div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeStrnKpi-vxcHk1k4zzbkGaJsYOMD=
bkfZNMVvCtswAogQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeStrnKp=
i-vxcHk1k4zzbkGaJsYOMDbkfZNMVvCtswAogQ%40mail.gmail.com</a>.<br />

--f403045e6c4abf5a5305536fd507--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 3 Jul 2017 13:50:07 -0700 (PDT)
Raw View
------=_Part_2096_232308588.1499115007248
Content-Type: multipart/alternative;
 boundary="----=_Part_2097_1814101434.1499115007249"

------=_Part_2097_1814101434.1499115007249
Content-Type: text/plain; charset="UTF-8"

On Monday, July 3, 2017 at 4:44:38 PM UTC-4, Brittany Friedman wrote:
>
> On Mon, Jul 3, 2017 at 3:21 PM, Bengt Gustafsson <bengt.gu...@beamways.com
> <javascript:>> wrote:
>
>> I would doubt that the runtime overhead of exceptions is worse than that
>> of checking return values and continue returning out the call stack.
>> Especially in the no-error case it should be more efficient as those ifs
>> have potentially large runtime penalty regardless of if the jump
>> instruction is taken or not, while the exception unwinding code is
>> typically very asymmetric with a minimized runtime cost for the non-throw
>> case.
>>
>> So before suggesting another mechanism that simplifies writing code based
>> on error returns I would suggest actually measuring the performance in the
>> throwing and non-throwing case compared to a return value/if-based
>> solution. This article is not totally clear but casts serious doubts about
>> any speed gain from avoiding exceptions:
>>
>>
>> https://stackoverflow.com/questions/13835817/are-exceptions-in-c-really-slow
>>
>> Unfortunately (or fortunately as it is so old) the TS report linked to
>> does not show numbers for exception handling. Maybe someone else can point
>> to a paper detailing the performance for the different approaches?
>>
>>
> There are plenty of reasons to use error codes or error-code-like-entities
> that are not motivated solely by performance considerations.
>
> Some users find error codes easier to audit and work with (no hidden
> control flow).
> Some users are on platforms that recommend against or forbid the use of
> exception handling. The platform vendor in question does not provide a
> high-quality exception handling mechanism.
> Some users don't want to pay for the *memory* overhead of the so-called
> """""""""zero cost""""""""" (there are not enough scare-quotes in the
> world) mechanism.
>
Exceptions do not compose well (see the now defunct exception_list)
>

Neither do error codes. Generally speaking, two sets of error codes from
two different libraries cannot be composed without creating a list of error
codes.

If we presume that exceptions can in *some* cases be slower, then if
> "errors" are very common or if you require *predictable* performance
> characteristics, exceptions may be unacceptable.
>

That's a "performance consideration".

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/12a8cbd7-49cc-4a4f-810d-39670fa1472a%40isocpp.org.

------=_Part_2097_1814101434.1499115007249
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Monday, July 3, 2017 at 4:44:38 PM UTC-4, Brittany Frie=
dman wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><d=
iv><div class=3D"gmail_quote">On Mon, Jul 3, 2017 at 3:21 PM, Bengt Gustafs=
son <span dir=3D"ltr">&lt;<a href=3D"javascript:" target=3D"_blank" gdf-obf=
uscated-mailto=3D"sFUZvYfWAQAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;javascri=
pt:&#39;;return true;">bengt.gu...@beamways.com</a><wbr>&gt;</span> wrote:<=
br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bord=
er-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">I wou=
ld doubt that the runtime overhead of exceptions is worse than that of chec=
king return values and continue returning out the call stack. Especially in=
 the no-error case it should be more efficient as those ifs have potentiall=
y large runtime penalty regardless of if the jump instruction is taken or n=
ot, while the exception unwinding code is typically very asymmetric with a =
minimized runtime cost for the non-throw case.<div><br></div><div>So before=
 suggesting another mechanism that simplifies writing code based on error r=
eturns I would suggest actually measuring the performance in the throwing a=
nd non-throwing case compared to a return value/if-based solution. This art=
icle is not totally clear but casts serious doubts about any speed gain fro=
m avoiding exceptions:</div><div><br></div><div><a href=3D"https://stackove=
rflow.com/questions/13835817/are-exceptions-in-c-really-slow" target=3D"_bl=
ank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.google.co=
m/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F13835817%2Fare-exc=
eptions-in-c-really-slow\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGxQJSKjIsm=
IsPOL0HqtDJdPmQ-DQ&#39;;return true;" onclick=3D"this.href=3D&#39;https://w=
ww.google.com/url?q\x3dhttps%3A%2F%2Fstackoverflow.com%2Fquestions%2F138358=
17%2Fare-exceptions-in-c-really-slow\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQj=
CNGxQJSKjIsmIsPOL0HqtDJdPmQ-DQ&#39;;return true;">https://stackoverflow.com=
/<wbr>questions/13835817/are-<wbr>exceptions-in-c-really-slow</a></div><div=
><br></div><div>Unfortunately (or fortunately as it is so old) the TS repor=
t linked to does not show numbers for exception handling. Maybe someone els=
e can point to a paper detailing the performance for the different approach=
es?<div><div><div><br></div></div></div></div></div></blockquote><div><br><=
/div><div>There are plenty of reasons to use error codes or error-code-like=
-entities that are not motivated solely by performance considerations.</div=
><div><br></div><div>Some users find error codes easier to audit and work w=
ith (no hidden control flow).</div><div>Some users are on platforms that re=
commend against or forbid the use of exception handling. The platform vendo=
r in question does not provide a high-quality exception handling mechanism.=
</div><div>Some users don&#39;t want to pay for the *memory* overhead of th=
e so-called &quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;zero cost=
&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;=C2=A0(there are not =
enough scare-quotes in the world) mechanism.</div></div></div></div></block=
quote><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><d=
iv class=3D"gmail_quote"><div>Exceptions do not compose well (see the now d=
efunct exception_list)</div></div></div></div></blockquote><div><br>Neither=
 do error codes. Generally speaking, two sets of error codes from two diffe=
rent libraries cannot be composed without creating a list of error codes.<b=
r><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
div><div class=3D"gmail_quote"><div>If we presume that exceptions can in *s=
ome* cases be slower, then if &quot;errors&quot; are very common or if you =
require *predictable* performance characteristics, exceptions may be unacce=
ptable.</div></div></div></div></blockquote><div><br>That&#39;s a &quot;per=
formance consideration&quot;.<br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/12a8cbd7-49cc-4a4f-810d-39670fa1472a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/12a8cbd7-49cc-4a4f-810d-39670fa1472a=
%40isocpp.org</a>.<br />

------=_Part_2097_1814101434.1499115007249--

------=_Part_2096_232308588.1499115007248--

.


Author: Brittany Friedman <fourthgeek@gmail.com>
Date: Mon, 3 Jul 2017 15:51:43 -0500
Raw View
--001a114a9f444626b505536fef44
Content-Type: text/plain; charset="UTF-8"

On Mon, Jul 3, 2017 at 3:50 PM, Nicol Bolas <jmckesson@gmail.com> wrote:

>
>> If we presume that exceptions can in *some* cases be slower, then if
>> "errors" are very common or if you require *predictable* performance
>> characteristics, exceptions may be unacceptable.
>>
>
> That's a "performance consideration".
>

Thank you for this enlightening feedback.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeQmGW5vTQO%3D2eA9S7FBb5S42vNuh0aMNfXV8saiFYStMQ%40mail.gmail.com.

--001a114a9f444626b505536fef44
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">On M=
on, Jul 3, 2017 at 3:50 PM, Nicol Bolas <span dir=3D"ltr">&lt;<a href=3D"ma=
ilto:jmckesson@gmail.com" target=3D"_blank">jmckesson@gmail.com</a>&gt;</sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;=
border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span class=
=3D""><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div class=
=3D"gmail_quote"><br>If we presume that exceptions can in *some* cases be s=
lower, then if &quot;errors&quot; are very common or if you require *predic=
table* performance characteristics, exceptions may be unacceptable.</div></=
div></blockquote></span><div><br>That&#39;s a &quot;performance considerati=
on&quot;.<br></div></div></blockquote><div><br></div><div>Thank you for thi=
s enlightening feedback.</div></div><br></div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeQmGW5vTQO%3D2eA9S7FBb5S42vNu=
h0aMNfXV8saiFYStMQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADbh%2BeQmGW=
5vTQO%3D2eA9S7FBb5S42vNuh0aMNfXV8saiFYStMQ%40mail.gmail.com</a>.<br />

--001a114a9f444626b505536fef44--

.


Author: Tim Teatro <timtro@gmail.com>
Date: Mon, 3 Jul 2017 19:43:21 -0700 (PDT)
Raw View
------=_Part_2214_1579157769.1499136201452
Content-Type: multipart/alternative;
 boundary="----=_Part_2215_2019065251.1499136201452"

------=_Part_2215_2019065251.1499136201452
Content-Type: text/plain; charset="UTF-8"

I have nothing to add on the discussion of using (or not using) exceptions.
I have no dog in that fight, but I do sometimes work in an areas where
exceptions are not an option.

If the decision is made to not use exceptions, then a solution to your
boilerplate problem is a monad. Monads (which you can think of as a design
pattern) make automatic a lot of the boilerplate that surrounds working
with container or embellished types. In your case, you want a container
which has your function's return value AND/OR a status code and you don't
want to have to deal with the boilerplate of packing, unpacking and
checking.

The simplest case of this sort of pattern is called the "maybe monad", and
is easily built around std::optional. An optional can contain a value (or
not), allowing failure, but you get no error code. It's not exactly what
you want, but it's easier to understand. Check out this portion of Phil
Nash's talk describing the std::optional based "maybe" monad (
https://youtu.be/8hW-LT8qFT0?t=51m2s ). If you feel like this solution is
right for you, and you want to kick it up a notch and get error codes, I'll
help you.



On Thursday, 29 June 2017 07:39:37 UTC-4, Igor Baidiuk wrote:
>
> There's a rather strange situation with error handling in C++, at least to
> me.
>
>    - Exception-based error handling is de-facto recommended way. It's
>    relatively ergonomic, allows to pass arbitrary info about error, gives ways
>    to filter exceptions by type. As a price, exceptions have runtime penalty,
>    require compiler support and are not reflected in function signatures -
>    checked exceptions were deprecated long ago, if I'm not mistaken. Also,
>    they're prohibited in some coding conventions (loike Google's) and
>    no-livers in lowlevel development.
>    - Exception-less error handling is based mostly on error codes. It
>    works everywhere, requires no special runtime support, and error type
>    (especially if it's a proper enum) is reflected in function signature -
>    which grants more compiler help. As a downside, the code which uses error
>    statuses often contains much boilerplate ("if (there-is-an-error) {
>    handle-error;} "), and error statuses are usually easy to omit and not
>    handle.
>
> What if we had ergonomics for error codes almost equal to exceptions?
>
>
> The issues with error code easy to not process and not carry any
> additional info are relatively easy to solve. There was a proposal to add
> std::expected type, which is a C++ implementation of Either/Result
> algebraic data type well known in FP world. Such a type would require
> explicit unpacking to get value and explicit checking if there's an error.
>
>
> The issue with status checking boilerplate is more complex though. In fact
> it requires that an expression is allowed to both declare expression-local
> variable and have return statement:
>
>    1. The result of function call is assigned to some temporary
>    2. The temporary is checked if it contains error
>    3. If there's an error, error-object is returned early from function
>    4. If there's an actual result, that result becomes result of
>    expression
>
> The main problem is that C++ has strict distinction between statements and
> expressions, and doesn't allow to mix them. Based on this, we need to
> either allow 'if' statement to be expression in some cases, or allow
> declaration statement and return statement to be used in ternary operator:
>
>
> auto result = if (auto&& __tmp__ = func_returning_result(), __tmp__.
> is_result())
>     { std::forward<decltype(func_returning_result())>(__tmp__).get_result();
> }
>     else { return std::forward<decltype(func_returning_result())>(__tmp__).get_error();
> };
>
> or, with ternary operator:
>
>
> auto result = (auto&& __tmp__ = func_returning_result(), __tmp__.is_result
> ()
>     ? std::forward<decltype(func_returning_result()
> )>(__tmp__).get_result()
>     : return std::forward<decltype(func_returning_result()
> )>(__tmp__).get_error());
>
> Of course, such boilerplate can be hidden behind macro - but
> "result-or-return expression" doesn't seem to be valid construct in current
> C++.
>
>
> Thoughts on this?
>
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e45db8a6-fbaf-449c-b91f-0f52a427c29f%40isocpp.org.

------=_Part_2215_2019065251.1499136201452
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I have nothing to add on the discussion of using (or =
not using) exceptions. I have no dog in that fight, but I do sometimes work=
 in an areas where exceptions are not an option.</div><div><br></div><div>I=
f the decision is made to not use exceptions, then a solution to your boile=
rplate problem is a monad. Monads (which you can think of as a design patte=
rn) make automatic a lot of the boilerplate that surrounds working with con=
tainer or embellished types. In your case, you want a container which has y=
our function&#39;s return value AND/OR a status code and you don&#39;t want=
 to have to deal with the boilerplate of packing, unpacking and checking.</=
div><div><br></div><div>The simplest case of this sort of pattern is called=
 the &quot;maybe monad&quot;, and is easily built around std::optional. An =
optional can contain a value (or not), allowing failure, but you get no err=
or code. It&#39;s not exactly what you want, but it&#39;s easier to underst=
and. Check out this portion of Phil Nash&#39;s talk describing the std::opt=
ional based &quot;maybe&quot; monad ( https://youtu.be/8hW-LT8qFT0?t=3D51m2=
s ). If you feel like this solution is right for you, and you want to kick =
it up a notch and get error codes, I&#39;ll help you.</div><div><br></div><=
div><br></div><br>On Thursday, 29 June 2017 07:39:37 UTC-4, Igor Baidiuk  w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">There&#3=
9;s a rather strange situation with error handling in C++, at least to me.<=
br><ul><li>Exception-based error handling is de-facto recommended way. It&#=
39;s relatively ergonomic, allows to pass arbitrary info about error, gives=
 ways to filter exceptions by type. As a price, exceptions have runtime pen=
alty, require compiler support and are not reflected in function signatures=
 - checked exceptions were deprecated long ago, if I&#39;m not mistaken. Al=
so, they&#39;re prohibited in some coding conventions (loike Google&#39;s) =
and no-livers in lowlevel development.<br></li><li>Exception-less error han=
dling is based mostly on error codes. It works everywhere, requires no spec=
ial runtime support, and error type (especially if it&#39;s a proper enum) =
is reflected in function signature - which grants more compiler help. As a =
downside, the code which uses error statuses often contains much boilerplat=
e (&quot;if (there-is-an-error) { handle-error;} &quot;), and error statuse=
s are usually easy to omit and not handle.</li></ul><p>What if we had ergon=
omics for error codes almost equal to exceptions?</p><p><br></p><p>The issu=
es with error code easy to not process and not carry any additional info ar=
e relatively easy to solve. There was a proposal to add std::expected type,=
 which is a C++ implementation of Either/Result algebraic data type well kn=
own in FP world. Such a type would require explicit unpacking to get value =
and explicit checking if there&#39;s an error.<br></p><p><br></p><p>The iss=
ue with status checking boilerplate is more complex though. In fact it requ=
ires that an expression is allowed to both declare expression-local variabl=
e and have return statement:</p><ol><li>The result of function call is assi=
gned to some temporary</li><li>The temporary is checked if it contains erro=
r</li><li>If there&#39;s an error, error-object is returned early from func=
tion</li><li>If there&#39;s an actual result, that result becomes result of=
 expression</li></ol><p>The main problem is that C++ has strict distinction=
 between statements and expressions, and doesn&#39;t allow to mix them. Bas=
ed on this, we need to either allow &#39;if&#39; statement to be expression=
 in some cases, or allow declaration statement and return statement to be u=
sed in ternary operator:</p><p><br></p><p></p><div style=3D"background-colo=
r:rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-=
width:1px"><code><div><span style=3D"color:#008">auto</span><span style=3D"=
color:#000"> result </span><span style=3D"color:#660">=3D</span><span style=
=3D"color:#000"> </span><span style=3D"color:#008">if</span><span style=3D"=
color:#000"> </span><span style=3D"color:#660">(</span><span style=3D"color=
:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span><span style=
=3D"color:#000"> __tmp__ </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> func_returning_result</span><span style=3D"color:#660=
">(),</span><span style=3D"color:#000"> __tmp__</span><span style=3D"color:=
#660">.</span><span style=3D"color:#000">is_result</span><span style=3D"col=
or:#660">())<br></span><span style=3D"color:#000"></span><span style=3D"col=
or:#660">=C2=A0=C2=A0=C2=A0 {</span><span style=3D"color:#000"> std</span><=
span style=3D"color:#660">::</span><span style=3D"color:#000">forward</span=
><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype<=
/span><span style=3D"color:#660">(</span><code><span style=3D"color:#000">f=
unc_<wbr>returning_result</span><span style=3D"color:#660">()</span><span s=
tyle=3D"color:#660">)&gt;(__tmp__).<wbr>get_result(); }<br>=C2=A0=C2=A0=C2=
=A0 else { return </span></code><code><span style=3D"color:#000">std</span>=
<span style=3D"color:#660">::</span><span style=3D"color:#000">forward</spa=
n><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype=
</span><span style=3D"color:#660">(</span><code><span style=3D"color:#000">=
func_<wbr>returning_result</span><span style=3D"color:#660">()</span><span =
style=3D"color:#660">)&gt;(__tmp__).<wbr>get_error(); };</span></code></cod=
e><span style=3D"color:#000"></span></div></code></div><br>or, with ternary=
 operator:<p></p><p><br></p><p></p><div style=3D"background-color:rgb(250,2=
50,250);border-color:rgb(187,187,187);border-style:solid;border-width:1px">=
<code><div><span style=3D"color:#606">auto result =3D (</span><span style=
=3D"color:#606"><code><span style=3D"color:#000"></span><span style=3D"colo=
r:#008">auto</span><span style=3D"color:#660">&amp;&amp;</span><span style=
=3D"color:#000"> __tmp__ </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> func_returning_result</span><span style=3D"color:#660=
">(),</span><span style=3D"color:#000"> __tmp__</span><span style=3D"color:=
#660">.</span><span style=3D"color:#000">is_result</span><span style=3D"col=
or:#660">()<br></span><span style=3D"color:#000"></span><span style=3D"colo=
r:#660">=C2=A0=C2=A0=C2=A0 ?</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">forward</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype</=
span><span style=3D"color:#660">(</span><code><span style=3D"color:#000">fu=
nc_<wbr>returning_result</span><span style=3D"color:#660">()</span><span st=
yle=3D"color:#660">)&gt;(__tmp__).<wbr>get_result()<br>=C2=A0=C2=A0=C2=A0 :=
 return </span></code><code><span style=3D"color:#000">std</span><span styl=
e=3D"color:#660">::</span><span style=3D"color:#000">forward</span><span st=
yle=3D"color:#660">&lt;</span><span style=3D"color:#008">decltype</span><sp=
an style=3D"color:#660">(</span><code><span style=3D"color:#000">func_<wbr>=
returning_result</span><span style=3D"color:#660">()</span><span style=3D"c=
olor:#660">)&gt;(__tmp__).<wbr>get_error());</span></code></code></code></s=
pan></div></code></div><br>Of course, such boilerplate can be hidden behind=
 macro - but &quot;result-or-return expression&quot; doesn&#39;t seem to be=
 valid construct in current C++.<p></p><p><br></p><p>Thoughts on this?<br><=
/p><br></div></blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e45db8a6-fbaf-449c-b91f-0f52a427c29f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e45db8a6-fbaf-449c-b91f-0f52a427c29f=
%40isocpp.org</a>.<br />

------=_Part_2215_2019065251.1499136201452--

------=_Part_2214_1579157769.1499136201452--

.


Author: Igor Baidiuk <target.san@gmail.com>
Date: Tue, 4 Jul 2017 23:27:32 -0700 (PDT)
Raw View
------=_Part_2762_1872713809.1499236052171
Content-Type: multipart/alternative;
 boundary="----=_Part_2763_1691279144.1499236052171"

------=_Part_2763_1691279144.1499236052171
Content-Type: text/plain; charset="UTF-8"

I'm well-aware of monadic approach to this problem.
If you use single monadic call chain as function body, it would become much
less readable, and simple control flow can be of an issue.
Otherwise, you'll end with if-else checks anyway.
Anyway, I saw some examples. They looked not very fitting for everyday work.

On Tuesday, July 4, 2017 at 5:43:21 AM UTC+3, Tim Teatro wrote:
>
> I have nothing to add on the discussion of using (or not using)
> exceptions. I have no dog in that fight, but I do sometimes work in an
> areas where exceptions are not an option.
>
> If the decision is made to not use exceptions, then a solution to your
> boilerplate problem is a monad. Monads (which you can think of as a design
> pattern) make automatic a lot of the boilerplate that surrounds working
> with container or embellished types. In your case, you want a container
> which has your function's return value AND/OR a status code and you don't
> want to have to deal with the boilerplate of packing, unpacking and
> checking.
>
> The simplest case of this sort of pattern is called the "maybe monad", and
> is easily built around std::optional. An optional can contain a value (or
> not), allowing failure, but you get no error code. It's not exactly what
> you want, but it's easier to understand. Check out this portion of Phil
> Nash's talk describing the std::optional based "maybe" monad (
> https://youtu.be/8hW-LT8qFT0?t=51m2s ). If you feel like this solution is
> right for you, and you want to kick it up a notch and get error codes, I'll
> help you.
>
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bc180deb-da9f-4c50-8862-f92c8af4d42a%40isocpp.org.

------=_Part_2763_1691279144.1499236052171
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I&#39;m well-aware of monadic approach to this problem.<br=
>If you use single monadic call chain as function body, it would become muc=
h less readable, and simple control flow can be of an issue.<br>Otherwise, =
you&#39;ll end with if-else checks anyway.<br>Anyway, I saw some examples. =
They looked not very fitting for everyday work.<br><br>On Tuesday, July 4, =
2017 at 5:43:21 AM UTC+3, Tim Teatro wrote:<blockquote class=3D"gmail_quote=
" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding=
-left: 1ex;"><div dir=3D"ltr"><div>I have nothing to add on the discussion =
of using (or not using) exceptions. I have no dog in that fight, but I do s=
ometimes work in an areas where exceptions are not an option.</div><div><br=
></div><div>If the decision is made to not use exceptions, then a solution =
to your boilerplate problem is a monad. Monads (which you can think of as a=
 design pattern) make automatic a lot of the boilerplate that surrounds wor=
king with container or embellished types. In your case, you want a containe=
r which has your function&#39;s return value AND/OR a status code and you d=
on&#39;t want to have to deal with the boilerplate of packing, unpacking an=
d checking.</div><div><br></div><div>The simplest case of this sort of patt=
ern is called the &quot;maybe monad&quot;, and is easily built around std::=
optional. An optional can contain a value (or not), allowing failure, but y=
ou get no error code. It&#39;s not exactly what you want, but it&#39;s easi=
er to understand. Check out this portion of Phil Nash&#39;s talk describing=
 the std::optional based &quot;maybe&quot; monad ( <a href=3D"https://youtu=
..be/8hW-LT8qFT0?t=3D51m2s" target=3D"_blank" rel=3D"nofollow" onmousedown=
=3D"this.href=3D&#39;https://youtu.be/8hW-LT8qFT0?t\x3d51m2s&#39;;return tr=
ue;" onclick=3D"this.href=3D&#39;https://youtu.be/8hW-LT8qFT0?t\x3d51m2s&#3=
9;;return true;">https://youtu.be/8hW-LT8qFT0?<wbr>t=3D51m2s</a> ). If you =
feel like this solution is right for you, and you want to kick it up a notc=
h and get error codes, I&#39;ll help you.</div><div><br></div></div></block=
quote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bc180deb-da9f-4c50-8862-f92c8af4d42a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bc180deb-da9f-4c50-8862-f92c8af4d42a=
%40isocpp.org</a>.<br />

------=_Part_2763_1691279144.1499236052171--

------=_Part_2762_1872713809.1499236052171--

.


Author: gmisocpp@gmail.com
Date: Thu, 6 Jul 2017 01:15:08 -0700 (PDT)
Raw View
------=_Part_3679_1995864229.1499328908128
Content-Type: multipart/alternative;
 boundary="----=_Part_3680_1580714411.1499328908129"

------=_Part_3680_1580714411.1499328908129
Content-Type: text/plain; charset="UTF-8"

So the op is proposing some kind of return early statement? Like this:

enum class open_file_status
{
    ok, file_not_found, file_locked, file_no_permission
};
struct open_file_result
{
    file_handle fh;
    open_file_status status_code;

    file_handle& value() {  return fh; }
    bool has_value()  {  return status_code == open_file_status::ok;  }
    get_status()  {  return status_code;  }
};

// If use like this (note new ?= syntax)
bool do_something_with_file()
{
    file_handle fh ?= open_file("not_there.txt") -> false;
}

// ?= is transformed to something like this:
bool do_something_with_file()
{
    auto __tmp{open_file("not_there.txt")};
    if (!__tmp.has_value())
        return false;
    // returns object after -> otherwise get_status if present, otherwise
__tmp
    file_handle fh = __tmp.value();
}

Why not offer something like that if that's what people want to use?

On Thursday, June 29, 2017 at 11:39:37 PM UTC+12, Igor Baidiuk wrote:

> There's a rather strange situation with error handling in C++, at least to
> me.
>
>    - Exception-based error handling is de-facto recommended way. It's
>    relatively ergonomic, allows to pass arbitrary info about error, gives ways
>    to filter exceptions by type. As a price, exceptions have runtime penalty,
>    require compiler support and are not reflected in function signatures -
>    checked exceptions were deprecated long ago, if I'm not mistaken. Also,
>    they're prohibited in some coding conventions (loike Google's) and
>    no-livers in lowlevel development.
>    - Exception-less error handling is based mostly on error codes. It
>    works everywhere, requires no special runtime support, and error type
>    (especially if it's a proper enum) is reflected in function signature -
>    which grants more compiler help. As a downside, the code which uses error
>    statuses often contains much boilerplate ("if (there-is-an-error) {
>    handle-error;} "), and error statuses are usually easy to omit and not
>    handle.
>
> What if we had ergonomics for error codes almost equal to exceptions?
>
>
> The issues with error code easy to not process and not carry any
> additional info are relatively easy to solve. There was a proposal to add
> std::expected type, which is a C++ implementation of Either/Result
> algebraic data type well known in FP world. Such a type would require
> explicit unpacking to get value and explicit checking if there's an error.
>
>
> The issue with status checking boilerplate is more complex though. In fact
> it requires that an expression is allowed to both declare expression-local
> variable and have return statement:
>
>    1. The result of function call is assigned to some temporary
>    2. The temporary is checked if it contains error
>    3. If there's an error, error-object is returned early from function
>    4. If there's an actual result, that result becomes result of
>    expression
>
> The main problem is that C++ has strict distinction between statements and
> expressions, and doesn't allow to mix them. Based on this, we need to
> either allow 'if' statement to be expression in some cases, or allow
> declaration statement and return statement to be used in ternary operator:
>
>
> auto result = if (auto&& __tmp__ = func_returning_result(), __tmp__.
> is_result())
>     { std::forward<decltype(func_returning_result())>(__tmp__).get_result();
> }
>     else { return std::forward<decltype(func_returning_result())>(__tmp__).get_error();
> };
>
> or, with ternary operator:
>
>
> auto result = (auto&& __tmp__ = func_returning_result(), __tmp__.is_result
> ()
>     ? std::forward<decltype(func_returning_result()
> )>(__tmp__).get_result()
>     : return std::forward<decltype(func_returning_result()
> )>(__tmp__).get_error());
>
> Of course, such boilerplate can be hidden behind macro - but
> "result-or-return expression" doesn't seem to be valid construct in current
> C++.
>
>
> Thoughts on this?
>
>

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3cec9280-8934-4630-95e4-006ef4a4e68a%40isocpp.org.

------=_Part_3680_1580714411.1499328908129
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>So the op is proposing some kind of return early=C2=
=A0statement? Like this:</div><div><br></div><div>enum class open_file_stat=
us<br>{<br>=C2=A0=C2=A0=C2=A0 ok, file_not_found, file_locked, file_no_perm=
ission<br>};</div><div>struct open_file_result<br>{<br>=C2=A0=C2=A0=C2=A0 f=
ile_handle fh;<br>=C2=A0=C2=A0=C2=A0 open_file_status status_code;<br>=C2=
=A0=C2=A0=C2=A0 <br>=C2=A0=C2=A0=C2=A0 file_handle&amp; value() {=C2=A0 ret=
urn fh; }<br>=C2=A0=C2=A0=C2=A0 bool has_value()=C2=A0 {=C2=A0 return statu=
s_code =3D=3D open_file_status::ok;=C2=A0 }</div><div>=C2=A0=C2=A0=C2=A0 ge=
t_status()=C2=A0 {=C2=A0 return status_code;=C2=A0=C2=A0}<br>};</div><div><=
br></div><div>// If use like this (note new ?=3D syntax)</div><div>bool do_=
something_with_file()<br>{<br>=C2=A0=C2=A0=C2=A0 file_handle fh ?=3D open_f=
ile(&quot;not_there.txt&quot;) -&gt; false;<br>}</div><div><br></div><div>/=
/ ?=3D is=C2=A0transformed to something like this:<br>bool do_something_wit=
h_file()<br>{<br>=C2=A0=C2=A0=C2=A0 auto __tmp{open_file(&quot;not_there.tx=
t&quot;)};<br>=C2=A0=C2=A0=C2=A0 if (!__tmp.has_value())<br>=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0 return false;</div><div>=C2=A0=C2=A0=C2=A0 //=
=C2=A0returns=C2=A0object after=C2=A0-&gt;=C2=A0otherwise get_status if pre=
sent, otherwise __tmp<br>=C2=A0=C2=A0=C2=A0 file_handle fh =3D __tmp.value(=
);<br>}<br></div><div><br></div><div>Why not offer something like that=C2=
=A0if that&#39;s what people want to use?<br><br>On Thursday, June 29, 2017=
 at 11:39:37 PM UTC+12, Igor Baidiuk wrote:</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-=
color: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid=
;"><div dir=3D"ltr">There&#39;s a rather strange situation with error handl=
ing in C++, at least to me.<br><ul><li>Exception-based error handling is de=
-facto recommended way. It&#39;s relatively ergonomic, allows to pass arbit=
rary info about error, gives ways to filter exceptions by type. As a price,=
 exceptions have runtime penalty, require compiler support and are not refl=
ected in function signatures - checked exceptions were deprecated long ago,=
 if I&#39;m not mistaken. Also, they&#39;re prohibited in some coding conve=
ntions (loike Google&#39;s) and no-livers in lowlevel development.<br></li>=
<li>Exception-less error handling is based mostly on error codes. It works =
everywhere, requires no special runtime support, and error type (especially=
 if it&#39;s a proper enum) is reflected in function signature - which gran=
ts more compiler help. As a downside, the code which uses error statuses of=
ten contains much boilerplate (&quot;if (there-is-an-error) { handle-error;=
} &quot;), and error statuses are usually easy to omit and not handle.</li>=
</ul><p>What if we had ergonomics for error codes almost equal to exception=
s?</p><p><br></p><p>The issues with error code easy to not process and not =
carry any additional info are relatively easy to solve. There was a proposa=
l to add std::expected type, which is a C++ implementation of Either/Result=
 algebraic data type well known in FP world. Such a type would require expl=
icit unpacking to get value and explicit checking if there&#39;s an error.<=
br></p><p><br></p><p>The issue with status checking boilerplate is more com=
plex though. In fact it requires that an expression is allowed to both decl=
are expression-local variable and have return statement:</p><ol><li>The res=
ult of function call is assigned to some temporary</li><li>The temporary is=
 checked if it contains error</li><li>If there&#39;s an error, error-object=
 is returned early from function</li><li>If there&#39;s an actual result, t=
hat result becomes result of expression</li></ol><p>The main problem is tha=
t C++ has strict distinction between statements and expressions, and doesn&=
#39;t allow to mix them. Based on this, we need to either allow &#39;if&#39=
; statement to be expression in some cases, or allow declaration statement =
and return statement to be used in ternary operator:</p><p><br></p><p></p><=
div style=3D"border: 1px solid rgb(187, 187, 187); border-image: none; back=
ground-color: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(0, =
0, 136);">auto</span><span style=3D"color: rgb(0, 0, 0);"> result </span><s=
pan style=3D"color: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(=
0, 0, 0);"> </span><span style=3D"color: rgb(0, 0, 136);">if</span><span st=
yle=3D"color: rgb(0, 0, 0);"> </span><span style=3D"color: rgb(102, 102, 0)=
;">(</span><span style=3D"color: rgb(0, 0, 136);">auto</span><span style=3D=
"color: rgb(102, 102, 0);">&amp;&amp;</span><span style=3D"color: rgb(0, 0,=
 0);"> __tmp__ </span><span style=3D"color: rgb(102, 102, 0);">=3D</span><s=
pan style=3D"color: rgb(0, 0, 0);"> func_returning_result</span><span style=
=3D"color: rgb(102, 102, 0);">(),</span><span style=3D"color: rgb(0, 0, 0);=
"> __tmp__</span><span style=3D"color: rgb(102, 102, 0);">.</span><span sty=
le=3D"color: rgb(0, 0, 0);">is_result</span><span style=3D"color: rgb(102, =
102, 0);">())<br></span><span style=3D"color: rgb(0, 0, 0);"></span><span s=
tyle=3D"color: rgb(102, 102, 0);">=C2=A0=C2=A0=C2=A0 {</span><span style=3D=
"color: rgb(0, 0, 0);"> std</span><span style=3D"color: rgb(102, 102, 0);">=
::</span><span style=3D"color: rgb(0, 0, 0);">forward</span><span style=3D"=
color: rgb(102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 136);"=
>decltype</span><span style=3D"color: rgb(102, 102, 0);">(</span><code><spa=
n style=3D"color: rgb(0, 0, 0);">func_<wbr>returning_result</span><span sty=
le=3D"color: rgb(102, 102, 0);">()</span><span style=3D"color: rgb(102, 102=
, 0);">)&gt;(__tmp__).<wbr>get_result(); }<br>=C2=A0=C2=A0=C2=A0 else { ret=
urn </span></code><code><span style=3D"color: rgb(0, 0, 0);">std</span><spa=
n style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, =
0, 0);">forward</span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><=
span style=3D"color: rgb(0, 0, 136);">decltype</span><span style=3D"color: =
rgb(102, 102, 0);">(</span><code><span style=3D"color: rgb(0, 0, 0);">func_=
<wbr>returning_result</span><span style=3D"color: rgb(102, 102, 0);">()</sp=
an><span style=3D"color: rgb(102, 102, 0);">)&gt;(__tmp__).<wbr>get_error()=
; };</span></code></code><span style=3D"color: rgb(0, 0, 0);"></span></div>=
</code></div><br>or, with ternary operator:<p></p><p><br></p><p></p><div st=
yle=3D"border: 1px solid rgb(187, 187, 187); border-image: none; background=
-color: rgb(250, 250, 250);"><code><div><span style=3D"color: rgb(102, 0, 1=
02);">auto result =3D (</span><span style=3D"color: rgb(102, 0, 102);"><cod=
e><span style=3D"color: rgb(0, 0, 0);"></span><span style=3D"color: rgb(0, =
0, 136);">auto</span><span style=3D"color: rgb(102, 102, 0);">&amp;&amp;</s=
pan><span style=3D"color: rgb(0, 0, 0);"> __tmp__ </span><span style=3D"col=
or: rgb(102, 102, 0);">=3D</span><span style=3D"color: rgb(0, 0, 0);"> func=
_returning_result</span><span style=3D"color: rgb(102, 102, 0);">(),</span>=
<span style=3D"color: rgb(0, 0, 0);"> __tmp__</span><span style=3D"color: r=
gb(102, 102, 0);">.</span><span style=3D"color: rgb(0, 0, 0);">is_result</s=
pan><span style=3D"color: rgb(102, 102, 0);">()<br></span><span style=3D"co=
lor: rgb(0, 0, 0);"></span><span style=3D"color: rgb(102, 102, 0);">=C2=A0=
=C2=A0=C2=A0 ?</span><span style=3D"color: rgb(0, 0, 0);"> std</span><span =
style=3D"color: rgb(102, 102, 0);">::</span><span style=3D"color: rgb(0, 0,=
 0);">forward</span><span style=3D"color: rgb(102, 102, 0);">&lt;</span><sp=
an style=3D"color: rgb(0, 0, 136);">decltype</span><span style=3D"color: rg=
b(102, 102, 0);">(</span><code><span style=3D"color: rgb(0, 0, 0);">func_<w=
br>returning_result</span><span style=3D"color: rgb(102, 102, 0);">()</span=
><span style=3D"color: rgb(102, 102, 0);">)&gt;(__tmp__).<wbr>get_result()<=
br>=C2=A0=C2=A0=C2=A0 : return </span></code><code><span style=3D"color: rg=
b(0, 0, 0);">std</span><span style=3D"color: rgb(102, 102, 0);">::</span><s=
pan style=3D"color: rgb(0, 0, 0);">forward</span><span style=3D"color: rgb(=
102, 102, 0);">&lt;</span><span style=3D"color: rgb(0, 0, 136);">decltype</=
span><span style=3D"color: rgb(102, 102, 0);">(</span><code><span style=3D"=
color: rgb(0, 0, 0);">func_<wbr>returning_result</span><span style=3D"color=
: rgb(102, 102, 0);">()</span><span style=3D"color: rgb(102, 102, 0);">)&gt=
;(__tmp__).<wbr>get_error());</span></code></code></code></span></div></cod=
e></div><br>Of course, such boilerplate can be hidden behind macro - but &q=
uot;result-or-return expression&quot; doesn&#39;t seem to be valid construc=
t in current C++.<p></p><p><br></p><p>Thoughts on this?<br></p><br></div></=
blockquote></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/3cec9280-8934-4630-95e4-006ef4a4e68a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3cec9280-8934-4630-95e4-006ef4a4e68a=
%40isocpp.org</a>.<br />

------=_Part_3680_1580714411.1499328908129--

------=_Part_3679_1995864229.1499328908128--

.