Topic: noexcept and static_assert


Author: denis bider <isocppgroup@denisbider.com>
Date: Thu, 23 Jul 2015 13:19:46 -0700 (PDT)
Raw View
------=_Part_887_944976413.1437682786425
Content-Type: multipart/alternative;
 boundary="----=_Part_888_1736337495.1437682786426"

------=_Part_888_1736337495.1437682786426
Content-Type: text/plain; charset=UTF-8

It is fairly awkward that I have to do this:


#define NoExcept(EXPR) \

    ([&]() { static_assert(noexcept(EXPR), "Expression can throw"); },
(EXPR))


in order to be able to do this:


Vect<T>& Swap(Vect<T>& x) noexcept

    { NoExcept(ContainerSwap(x)); return *this; }


There should be an easier way to use the noexcept operator with
static_assert.


It is furthermore awkward that static_assert must be a statement, instead
of an expression, requiring the above lambda construction.

It's 2015, why are we still making statements that can't serve as
expressions...?



--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_888_1736337495.1437682786426
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>It is fairly awkward that I have to do this:</div><di=
v><br></div><div><br></div><div><p><font color=3D"#0000ff" face=3D"Consolas=
" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font col=
or=3D"#0000ff" face=3D"Consolas" size=3D"2">#define</font></font></font><fo=
nt face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font>=
</font><font color=3D"#6f008a" face=3D"Consolas" size=3D"2"><font color=3D"=
#6f008a" face=3D"Consolas" size=3D"2"><font color=3D"#6f008a" face=3D"Conso=
las" size=3D"2">NoExcept</font></font></font><font face=3D"Consolas" size=
=3D"2"><font face=3D"Consolas" size=3D"2">(EXPR) \</font></font></p><font f=
ace=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> =C2=A0=C2=A0=C2=A0 ([&amp;]() { </font></font><font color=3D"#=
0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">static_=
assert</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D=
"Consolas" size=3D"2">(</font></font><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">(EXPR=
), </font></font><font color=3D"#a31515" face=3D"Consolas" size=3D"2"><font=
 color=3D"#a31515" face=3D"Consolas" size=3D"2"><font color=3D"#a31515" fac=
e=3D"Consolas" size=3D"2">&quot;Expression can throw&quot;</font></font></f=
ont><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">)=
; }, (EXPR))</font></font></p></div><div><br></div><div><br></div><div>in o=
rder to be able to do this:</div><div><br></div><div><br></div><div><p><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2">Vect</font></font></font><font face=3D"Consolas" size=3D"2"><font fa=
ce=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;&amp; Swap(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">Vect</font></font></font><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></fo=
nt><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas"=
 size=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">&gt;&amp; </font></font><font color=3D"#808080=
" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">x</font></fon=
t></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D=
"2">) </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">noexcept</font></font></font></p><p><font face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff">=C2=A0=C2=A0=C2=A0 </font>=
{ <font color=3D"#6f008a"><font color=3D"#6f008a"><font color=3D"#6f008a">N=
oExcept</font></font></font>(ContainerSwap(x)); <font color=3D"#0000ff"><fo=
nt color=3D"#0000ff"><font color=3D"#0000ff">return</font></font></font> *<=
font color=3D"#0000ff"><font color=3D"#0000ff"><font color=3D"#0000ff">this=
</font></font></font>; }</font></p></div><div><br></div><div><br></div><div=
>There should be an easier way to use the <font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></=
font> operator with <font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">static_assert</font></font></font>.</div><div>=
<br></div><div><br></div><div>It is furthermore awkward that <font color=3D=
"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Cons=
olas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">stati=
c_assert</font></font></font> must be a statement, instead of an expression=
, requiring the above lambda construction.</div><div><br></div><div>It&#39;=
s 2015, why are we still making statements that can&#39;t serve as expressi=
ons...?</div><div><br></div><div><br></div><div><br></div></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_888_1736337495.1437682786426--
------=_Part_887_944976413.1437682786425--

.


Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Thu, 23 Jul 2015 17:19:13 -0700 (PDT)
Raw View
------=_Part_52_1657614028.1437697153958
Content-Type: multipart/alternative;
 boundary="----=_Part_53_697698507.1437697153958"

------=_Part_53_697698507.1437697153958
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, July 23, 2015 at 1:19:46 PM UTC-7, denis bider wrote:
>
> It is fairly awkward that I have to do this:
>
>
> #define NoExcept(EXPR) \
>
>     ([&]() { static_assert(noexcept(EXPR), "Expression can throw"); },=20
> (EXPR))
>
>
> in order to be able to do this:
>
>
> Vect<T>& Swap(Vect<T>& x) noexcept
>
>     { NoExcept(ContainerSwap(x)); return *this; }
>
>
> There should be an easier way to use the noexcept operator with=20
> static_assert.
>

Have you tried

    Vect<T>& Swap(Vect<T>& x) noexcept
    {
        static_assert(noexcept(ContainerSwap(x)));
        ContainerSwap(x);
        return *this;
    }

?

Alternatively, just mark ContainerSwap as noexcept (assuming you control=20
its code). It definitely shouldn't be throwing anything.

Alternatively, just forget about marking things noexcept and move on. I=20
have yet to see *any* in-game effect of noexcept, except for the=20
std::vector::resize misfeature (that it uses move-construction iff you've=
=20
marked your move-constructor noexcept, and otherwise falls back to slow=20
copy-construction).

=E2=80=93Arthur

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_53_697698507.1437697153958
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, July 23, 2015 at 1:19:46 PM UTC-7, denis bider wrote:<blockquo=
te 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>It is fairly awkw=
ard that I have to do this:</div><div><br></div><div><br></div><div><p><fon=
t color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=
=3D"2">#define</font></font></font><font face=3D"Consolas" size=3D"2"><font=
 face=3D"Consolas" size=3D"2"> </font></font><font color=3D"#6f008a" face=
=3D"Consolas" size=3D"2"><font color=3D"#6f008a" face=3D"Consolas" size=3D"=
2"><font color=3D"#6f008a" face=3D"Consolas" size=3D"2">NoExcept</font></fo=
nt></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=
=3D"2">(EXPR) \</font></font></p><font face=3D"Consolas" size=3D"2"><font f=
ace=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> =C2=A0=C2=A0=C2=A0 ([&amp;]() { </font></font><font color=3D"#=
0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">static_=
assert</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D=
"Consolas" size=3D"2">(</font></font><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">(EXPR=
), </font></font><font color=3D"#a31515" face=3D"Consolas" size=3D"2"><font=
 color=3D"#a31515" face=3D"Consolas" size=3D"2"><font color=3D"#a31515" fac=
e=3D"Consolas" size=3D"2">&quot;Expression can throw&quot;</font></font></f=
ont><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">)=
; }, (EXPR))</font></font></p></div><div><br></div><div><br></div><div>in o=
rder to be able to do this:</div><div><br></div><div><br></div><div><p><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2">Vect</font></font></font><font face=3D"Consolas" size=3D"2"><font fa=
ce=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;&amp; Swap(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">Vect</font></font></font><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></fo=
nt><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas"=
 size=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">&gt;&amp; </font></font><font color=3D"#808080=
" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">x</font></fon=
t></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D=
"2">) </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">noexcept</font></font></font></p><p><font face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff">=C2=A0=C2=A0=C2=A0 </font>=
{ <font color=3D"#6f008a"><font color=3D"#6f008a"><font color=3D"#6f008a">N=
oExcept</font></font></font>(ContainerSwap(x)); <font color=3D"#0000ff"><fo=
nt color=3D"#0000ff"><font color=3D"#0000ff">return</font></font></font> *<=
font color=3D"#0000ff"><font color=3D"#0000ff"><font color=3D"#0000ff">this=
</font></font></font>; }</font></p></div><div><br></div><div><br></div><div=
>There should be an easier way to use the <font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></=
font> operator with <font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">static_assert</font></font></font>.</div></div=
></blockquote><div><br></div><div>Have you tried</div><div><br></div><div><=
font face=3D"courier new, monospace">=C2=A0 =C2=A0 Vect&lt;T&gt;&amp; Swap(=
Vect&lt;T&gt;&amp; x) noexcept</font></div><div><font face=3D"courier new, =
monospace">=C2=A0=C2=A0 =C2=A0{</font></div><div><font face=3D"courier new,=
 monospace">=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0static_assert(noexcept(Contain=
erSwap(x)));</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 ContainerSwap(x);</font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return *this;</font></div><d=
iv><font face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div><div><=
br></div><div>?</div><div><br></div><div>Alternatively, just mark Container=
Swap as noexcept (assuming you control its code). It definitely shouldn&#39=
;t be throwing anything.</div><div><br></div><div>Alternatively, just forge=
t about marking things noexcept and move on. I have yet to see <i>any</i> i=
n-game effect of noexcept, except for the std::vector::resize misfeature (t=
hat it uses move-construction iff you&#39;ve marked your move-constructor n=
oexcept, and otherwise falls back to slow copy-construction).</div><div><br=
></div><div>=E2=80=93Arthur</div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_53_697698507.1437697153958--
------=_Part_52_1657614028.1437697153958--

.


Author: denis bider <isocppgroup@denisbider.com>
Date: Thu, 23 Jul 2015 18:24:38 -0700 (PDT)
Raw View
------=_Part_109_896313710.1437701078277
Content-Type: multipart/alternative;
 boundary="----=_Part_110_1547261694.1437701078277"

------=_Part_110_1547261694.1437701078277
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

You suggest code duplication, which is exactly what I'm trying to avoid. :)

The thing about exception safety is that you *never* see effects if it's=20
done properly.

I need noexcept because my container implementation requires=20
is_nothrow_move_constructible and is_nothrow_destructible to provide strong=
=20
exception safety. I have already caught a bug this way - assuming an STL=20
class was nothrow move constructible, and it turns out, with my compiler,=
=20
it isn't.

The macro is neat, and it works great. But it shouldn't *have* to be a=20
macro. I am genuinely befuddled why the noexcept operator does not already=
=20
work this way. It should pass through the expression result, or static=20
assert if the expression can throw.


On Thursday, July 23, 2015 at 6:19:14 PM UTC-6, Arthur O'Dwyer wrote:

> On Thursday, July 23, 2015 at 1:19:46 PM UTC-7, denis bider wrote:
>>
>> It is fairly awkward that I have to do this:
>>
>>
>> #define NoExcept(EXPR) \
>>
>>     ([&]() { static_assert(noexcept(EXPR), "Expression can throw"); },=
=20
>> (EXPR))
>>
>>
>> in order to be able to do this:
>>
>>
>> Vect<T>& Swap(Vect<T>& x) noexcept
>>
>>     { NoExcept(ContainerSwap(x)); return *this; }
>>
>>
>> There should be an easier way to use the noexcept operator with=20
>> static_assert.
>>
>
> Have you tried
>
>     Vect<T>& Swap(Vect<T>& x) noexcept
>     {
>         static_assert(noexcept(ContainerSwap(x)));
>         ContainerSwap(x);
>         return *this;
>     }
>
> ?
>
> Alternatively, just mark ContainerSwap as noexcept (assuming you control=
=20
> its code). It definitely shouldn't be throwing anything.
>
> Alternatively, just forget about marking things noexcept and move on. I=
=20
> have yet to see *any* in-game effect of noexcept, except for the=20
> std::vector::resize misfeature (that it uses move-construction iff you've=
=20
> marked your move-constructor noexcept, and otherwise falls back to slow=
=20
> copy-construction).
>
> =E2=80=93Arthur
>

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_110_1547261694.1437701078277
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>You suggest code duplication, which is exactly what I=
&#39;m trying to avoid. :)</div><div><br></div><div>The thing about excepti=
on safety is that you <em>never</em> see effects if it&#39;s done properly.=
</div><div><br></div><div>I need <font face=3D"courier new,monospace">noexc=
ept</font> because=C2=A0my container implementation requires=C2=A0<font fac=
e=3D"courier new,monospace">is_nothrow_move_constructible</font> and <font =
face=3D"courier new,monospace">is_nothrow_destructible</font> to provide st=
rong exception safety. I have already caught a bug this way - assuming an S=
TL class was nothrow move constructible, and it turns out, with=C2=A0my com=
piler, it isn&#39;t.</div><div><br></div><div>The macro is neat, and it wor=
ks great.=C2=A0But it shouldn&#39;t <em>have</em> to be a macro. I am genui=
nely befuddled why the <font face=3D"courier new,monospace">noexcept</font>=
 operator does not already work this way. It should pass through the expres=
sion result, or static assert if the expression can throw.</div><div><br><b=
r>On Thursday, July 23, 2015 at 6:19:14 PM UTC-6, Arthur O&#39;Dwyer 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-widt=
h: 1px; border-left-style: solid;">On Thursday, July 23, 2015 at 1:19:46 PM=
 UTC-7, denis bider wrote:<blockquote class=3D"gmail_quote" style=3D"margin=
: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 20=
4); border-left-width: 1px; border-left-style: solid;"><div dir=3D"ltr"><di=
v>It is fairly awkward that I have to do this:</div><div><br></div><div><br=
></div><div><p><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=
=3D"Consolas" size=3D"2">#define</font></font></font><font face=3D"Consolas=
" size=3D"2"><font face=3D"Consolas" size=3D"2"> </font></font><font color=
=3D"#6f008a" face=3D"Consolas" size=3D"2"><font color=3D"#6f008a" face=3D"C=
onsolas" size=3D"2"><font color=3D"#6f008a" face=3D"Consolas" size=3D"2">No=
Except</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D=
"Consolas" size=3D"2">(EXPR) \</font></font></p><font face=3D"Consolas" siz=
e=3D"2"><font face=3D"Consolas" size=3D"2">
</font></font><p><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas"=
 size=3D"2"> =C2=A0=C2=A0=C2=A0 ([&amp;]() { </font></font><font color=3D"#=
0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2">static_=
assert</font></font></font><font face=3D"Consolas" size=3D"2"><font face=3D=
"Consolas" size=3D"2">(</font></font><font color=3D"#0000ff" face=3D"Consol=
as" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font c=
olor=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></font>=
<font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">(EXPR=
), </font></font><font color=3D"#a31515" face=3D"Consolas" size=3D"2"><font=
 color=3D"#a31515" face=3D"Consolas" size=3D"2"><font color=3D"#a31515" fac=
e=3D"Consolas" size=3D"2">&quot;Expression can throw&quot;</font></font></f=
ont><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">)=
; }, (EXPR))</font></font></p></div><div><br></div><div><br></div><div>in o=
rder to be able to do this:</div><div><br></div><div><br></div><div><p><fon=
t color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" fa=
ce=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2">Vect</font></font></font><font face=3D"Consolas" size=3D"2"><font fa=
ce=3D"Consolas" size=3D"2">&lt;</font></font><font color=3D"#2b91af" face=
=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"=
2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2">T</font></font></fo=
nt><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&g=
t;&amp; Swap(</font></font><font color=3D"#2b91af" face=3D"Consolas" size=
=3D"2"><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"=
#2b91af" face=3D"Consolas" size=3D"2">Vect</font></font></font><font face=
=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D"2">&lt;</font></fo=
nt><font color=3D"#2b91af" face=3D"Consolas" size=3D"2"><font color=3D"#2b9=
1af" face=3D"Consolas" size=3D"2"><font color=3D"#2b91af" face=3D"Consolas"=
 size=3D"2">T</font></font></font><font face=3D"Consolas" size=3D"2"><font =
face=3D"Consolas" size=3D"2">&gt;&amp; </font></font><font color=3D"#808080=
" face=3D"Consolas" size=3D"2"><font color=3D"#808080" face=3D"Consolas" si=
ze=3D"2"><font color=3D"#808080" face=3D"Consolas" size=3D"2">x</font></fon=
t></font><font face=3D"Consolas" size=3D"2"><font face=3D"Consolas" size=3D=
"2">) </font></font><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">noexcept</font></font></font></p><p><font face=
=3D"Consolas" size=3D"2"><font color=3D"#0000ff">=C2=A0=C2=A0=C2=A0 </font>=
{ <font color=3D"#6f008a"><font color=3D"#6f008a"><font color=3D"#6f008a">N=
oExcept</font></font></font>(ContainerSwap(x)); <font color=3D"#0000ff"><fo=
nt color=3D"#0000ff"><font color=3D"#0000ff">return</font></font></font> *<=
font color=3D"#0000ff"><font color=3D"#0000ff"><font color=3D"#0000ff">this=
</font></font></font>; }</font></p></div><div><br></div><div><br></div><div=
>There should be an easier way to use the <font color=3D"#0000ff" face=3D"C=
onsolas" size=3D"2"><font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2">noexcept</font></font></=
font> operator with <font color=3D"#0000ff" face=3D"Consolas" size=3D"2"><f=
ont color=3D"#0000ff" face=3D"Consolas" size=3D"2"><font color=3D"#0000ff" =
face=3D"Consolas" size=3D"2">static_assert</font></font></font>.</div></div=
></blockquote><div><br></div><div>Have you tried</div><div><br></div><div><=
font face=3D"courier new, monospace">=C2=A0 =C2=A0 Vect&lt;T&gt;&amp; Swap(=
Vect&lt;T&gt;&amp; x) noexcept</font></div><div><font face=3D"courier new, =
monospace">=C2=A0=C2=A0 =C2=A0{</font></div><div><font face=3D"courier new,=
 monospace">=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0static_assert(noexcept(Contain=
erSwap(x)));</font></div><div><font face=3D"courier new, monospace">=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 ContainerSwap(x);</font></div><div><font face=3D"couri=
er new, monospace">=C2=A0 =C2=A0 =C2=A0 =C2=A0 return *this;</font></div><d=
iv><font face=3D"courier new, monospace">=C2=A0 =C2=A0 }</font></div><div><=
br></div><div>?</div><div><br></div><div>Alternatively, just mark Container=
Swap as noexcept (assuming you control its code). It definitely shouldn&#39=
;t be throwing anything.</div><div><br></div><div>Alternatively, just forge=
t about marking things noexcept and move on. I have yet to see <i>any</i> i=
n-game effect of noexcept, except for the std::vector::resize misfeature (t=
hat it uses move-construction iff you&#39;ve marked your move-constructor n=
oexcept, and otherwise falls back to slow copy-construction).</div><div><br=
></div><div>=E2=80=93Arthur</div></blockquote></div>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_110_1547261694.1437701078277--
------=_Part_109_896313710.1437701078277--

.


Author: David Krauss <potswa@gmail.com>
Date: Fri, 24 Jul 2015 10:36:52 +0800
Raw View
--Apple-Mail=_CF79BBBA-80A6-4ABB-95C1-B8B92B5EAA50
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8


> On 2015=E2=80=9307=E2=80=9324, at 9:24 AM, denis bider <isocppgroup@denis=
bider.com> wrote:
>=20
> You suggest code duplication, which is exactly what I'm trying to avoid. =
:)
>=20
> The thing about exception safety is that you never see effects if it's do=
ne properly.

The noexcept operator is associated with duplication in more situations. A =
very common idiom is duplication of a function=E2=80=99s body into its exce=
ption specification using noexcept.

void foo() noexcept( dosomething() )
    { return dosomething(); }

The solution is to introduce noexcept(auto):

void foo() noexcept(auto)
    { return dosomething(); }

This potentially solves at least some cases of duplication in unconditional=
ly noexcept functions.

Given sufficiently relaxed rules we could have this:

void foo() noexcept(auto) {
    return dosomething();
    // The "noexcept(auto)" could be considered resolved after the last eva=
luated expression in the function.
    static_assert( noexcept( foo() ) );
}

Alternatively (and perhaps better), a helper function could encapsulate the=
 duplication:

template< typename fn, typename ... arg >
decltype(auto) invoke_require_noexcept( fn && f, arg && ... a ) noexcept {
    static_assert( noexcept( std::invoke( std::forward< fn >( f ), std::for=
ward< arg >( a ) ... ) ) );
    return std::invoke( std::forward< fn >( f ), std::forward< arg >( a ) .=
... );
}

void foo() noexcept
    { return invoke_require_noexcept( []() noexcept(auto) { dosomething() }=
 ); }

Given noexcept(auto), perhaps it be the default for lambda expressions.

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

--Apple-Mail=_CF79BBBA-80A6-4ABB-95C1-B8B92B5EAA50
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9307=
=E2=80=9324, at 9:24 AM, denis bider &lt;<a href=3D"mailto:isocppgroup@deni=
sbider.com" class=3D"">isocppgroup@denisbider.com</a>&gt; wrote:</div><br c=
lass=3D"Apple-interchange-newline"><div class=3D""><div dir=3D"ltr" class=
=3D""><div class=3D"">You suggest code duplication, which is exactly what I=
'm trying to avoid. :)</div><div class=3D""><br class=3D""></div><div class=
=3D"">The thing about exception safety is that you <em class=3D"">never</em=
> see effects if it's done properly.</div></div></div></blockquote><div><br=
 class=3D""></div><div>The&nbsp;<span style=3D"font-family: Courier;" class=
=3D"">noexcept</span>&nbsp;operator is associated with duplication in more =
situations. A very common idiom is duplication of a function=E2=80=99s body=
 into its exception specification using <font face=3D"Courier" class=3D"">n=
oexcept</font>.</div><div><br class=3D""></div><div><font face=3D"Courier" =
class=3D"">void foo() noexcept( dosomething() )</font></div><div><font face=
=3D"Courier" class=3D"">&nbsp; &nbsp; { return dosomething(); }</font></div=
><div><br class=3D""></div><div>The solution is to introduce <font face=3D"=
Courier" class=3D"">noexcept(auto)</font>:</div><div><br class=3D""></div><=
div><div><font face=3D"Courier" class=3D"">void foo() noexcept(auto)</font>=
</div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; { return dosomet=
hing(); }</font></div><div class=3D""><font face=3D"Courier" class=3D""><br=
 class=3D""></font></div></div><div>This potentially solves at least some c=
ases of duplication in unconditionally&nbsp;<span style=3D"font-family: Cou=
rier;" class=3D"">noexcept</span>&nbsp;functions.</div><div><br class=3D"">=
</div><div>Given sufficiently relaxed rules we could have this:</div><div><=
br class=3D""></div><div><div><font face=3D"Courier" class=3D"">void foo() =
noexcept(auto) {</font></div><div><font face=3D"Courier" class=3D"">&nbsp; =
&nbsp; return dosomething();</font></div><div><font face=3D"Courier" class=
=3D"">&nbsp; &nbsp; // The "noexcept(auto)" could be considered resolved af=
ter the last evaluated expression in the function.</font></div><div><font f=
ace=3D"Courier" class=3D"">&nbsp; &nbsp; static_assert( noexcept( foo() ) )=
;</font></div><div><font face=3D"Courier" class=3D"">}</font></div><div cla=
ss=3D""><font face=3D"Courier" class=3D""><br class=3D""></font></div></div=
><div>Alternatively (and perhaps better), a helper function could encapsula=
te the duplication:</div><div><br class=3D""></div><div><div><font face=3D"=
Courier" class=3D"">template&lt; typename fn, typename ... arg &gt;</font><=
/div><div><font face=3D"Courier" class=3D"">decltype(auto) invoke_require_n=
oexcept( fn &amp;&amp; f, arg &amp;&amp; ... a ) noexcept {</font></div><di=
v><font face=3D"Courier" class=3D"">&nbsp; &nbsp; static_assert( noexcept(&=
nbsp;</font><font face=3D"Courier" class=3D"">std::invoke(&nbsp;std::forwar=
d&lt; fn &gt;( f ), std::forward&lt; arg &gt;( a )&nbsp;... ) )&nbsp;);</fo=
nt></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; return std::i=
nvoke(&nbsp;</font><span style=3D"font-family: Courier;" class=3D"">std::fo=
rward&lt; fn &gt;( f ), std::forward&lt; arg &gt;( a ) ... )</span><font fa=
ce=3D"Courier" class=3D"">;</font></div><div><font face=3D"Courier" class=
=3D"">}</font></div><div><font face=3D"Courier" class=3D""><br class=3D""><=
/font></div><div><font face=3D"Courier" class=3D"">void foo() noexcept</fon=
t></div><div><font face=3D"Courier" class=3D"">&nbsp; &nbsp; { return&nbsp;=
</font><span style=3D"font-family: Courier;" class=3D"">invoke_require_noex=
cept</span><font face=3D"Courier" class=3D"">( []() noexcept(auto) { dosome=
thing() } ); }</font></div><div><br class=3D""></div></div><div>Given&nbsp;=
<font face=3D"Courier" class=3D"">noexcept(auto)</font>, perhaps it be the =
default for lambda expressions.</div><div><br class=3D""></div></div></body=
></html>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--Apple-Mail=_CF79BBBA-80A6-4ABB-95C1-B8B92B5EAA50--

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 23 Jul 2015 19:38:09 -0700
Raw View
On Thursday 23 July 2015 18:24:38 denis bider wrote:
> The macro is neat, and it works great. But it shouldn't *have* to be a
> macro. I am genuinely befuddled why the noexcept operator does not already
> work this way. It should pass through the expression result, or static
> assert if the expression can throw.

 if (noexcept(foo())
  bar();
 else
  baz();

The above should neither call foo ("pass through the expression result") nor
static assert.

The above is provided so that bar() could be an specialised version of baz()
for when the expression is noexcept.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

.


Author: Thiago Macieira <thiago@macieira.org>
Date: Thu, 23 Jul 2015 19:56:13 -0700
Raw View
On Friday 24 July 2015 10:36:52 David Krauss wrote:
> The noexcept operator is associated with duplication in more situations. =
A
> very common idiom is duplication of a function=E2=80=99s body into its ex=
ception
> specification using noexcept.
>=20
> void foo() noexcept( dosomething() )
>     { return dosomething(); }
>=20
> The solution is to introduce noexcept(auto):
>=20
> void foo() noexcept(auto)
>     { return dosomething(); }

We discussed this before, but refresh my mind please: did we agree that=20
noexcept(auto) should be the default for inline functions?

If the entire body of a function is noexcept, it can't throw. If the functi=
on=20
is inline, then changing it so it later throws but not recompiling everythi=
ng=20
is an ODR violation. The standard wouldn't care.

For ABI binary compatibility, the only case that would be problematic is wh=
en:
 a) the function was inline and thus implicitly noexcept
 b) the function was called but not inlined
 c) the out-of-line copy is subject to merging across multiple libraries
 d) the function was de-inlined and made to throw
 e) the dynamic linker chose to call the copy that throws

I find that to be very unlikely to happen, for the following reasons:
 1) inline functions get often inlined
 2) a good portion of C++ libraries don't try to keep binary compatibility=
=20
    (boost doesn't even try, for example)
 3) of those that do, deinlining is a very uncommon thing to do
 4) of those that do keep binary compatibility, a good chunk follow Qt's=20
    paradigm and don't use exceptions
 5) on modern operating systems with modern C++ shared libraries that try t=
o=20
    keep binary compatibility, out-of-line copy of inline functions are not=
=20
    merged across shared library boundaries (-fvisibility-inlines-hidden; f=
or=20
    MSVC, this applies too, except for debug-mode calls to inline member=20
    functions in classes that are __declspec(dllexport)).

--=20
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
      PGP/GPG: 0x6EF45358; fingerprint:
      E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358

--=20

---=20
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 e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

.