Topic: c++17 language support for arithmetic operations
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Wed, 3 Jun 2015 16:16:08 -0700 (PDT)
Raw View
------=_Part_2012_1897229860.1433373368721
Content-Type: multipart/alternative;
boundary="----=_Part_2013_905066364.1433373368722"
------=_Part_2013_905066364.1433373368722
Content-Type: text/plain; charset=UTF-8
Hi folks
Just preliminary proposal:
Compiler gcc offers built-in function to do basic arithmetic operations with overflow/carry.
https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
It would be great if the C++ language itself supported this operations even for arithmetic operators for better readability
and better optimization.
There are two possibilities I can think of:
//Variant 1: using global functions to set/get flags after/before arithmetic operations.
#include <inttypes.h>
#include <assert.h>
#include <flags>
//void set_overflow_flag(bool b);
//bool overflow_flag();
int main()
{
uint64_t a=~0;
set_overflow_flag(false);//hint to compiler/optimizer
a+=5;
assert(overflow_flag());
assert(a==4);
return 0;
}
//Variant 2:
// to extend the operators syntax on integral built-in types to allow to capture the extra overflow/carry flag bit (bool)
// or higher word in multiplications
// [] for overflow(hi part)/ in unsigned arithmetics , {} for carry in signed arithmetics
uint64_t a=~0;
uint64_t b=0;
bool overflow;
[overflow]b=a+2;
assert(b==1);
assert(of);
//multiplication:
uint64_t a=1<<63;
uint64_t b=1<<1;
uint64_t c;
uint64_t d;
[c]d=a*b;
I am interested in a feedback if this would be a useful extension and if there are any potential problems.
Also can someone formalize the proposal?
Marian Klein
--
---
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_2013_905066364.1433373368722
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">
<pre>Hi folks</pre><pre><br></pre><pre>Just preliminary proposal:</pre><pre=
><br></pre><pre>Compiler gcc offers built-in function to do basic arithmeti=
c operations with overflow/carry. </pre><pre><span style=3D"color: rgb(0, 1=
28, 0);">https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html<=
/span></pre><pre><br></pre><pre>It would be great if the C++ language itsel=
f supported this operations even for arithmetic operators for better readab=
ility</pre><pre>and better optimization.</pre><pre><br></pre><pre>There are=
two possibilities I can think of:</pre><pre>//Variant 1: using global func=
tions to set/get flags after/before arithmetic operations.</pre><pre><!--St=
artFragment--><span style=3D" color:#000080;">#include</span><span style=3D=
" color:#c0c0c0;"> </span><span style=3D" color:#008000;"><inttypes.h>=
;</span></pre>
<pre><span style=3D" color:#000080;">#include</span><span style=3D" color:#=
c0c0c0;"> </span><span style=3D" color:#008000;"><assert.h></span></p=
re>
<pre><span style=3D" color:#000080;">#include</span><span style=3D" color:#=
c0c0c0;"> </span><span style=3D" color:#008000;"><flags></span></pre>
<pre><br></pre>
<pre><span style=3D" color:#008000;">//void</span><span style=3D" color:#c0=
c0c0;"> </span><span style=3D" color:#008000;">set_overflow_flag(bool</span=
><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#008000;">b)=
;</span></pre>
<pre><span style=3D" color:#008000;">//bool</span><span style=3D" color:#c0=
c0c0;"> </span><span style=3D" color:#008000;">overflow_flag();</span></pre=
>
<pre><br></pre>
<pre><span style=3D" color:#808000;">int</span><span style=3D" color:#c0c0c=
0;"> </span><span style=3D" color:#000000;">main</span><span style=3D" colo=
r:#000000;">()</span></pre>
<pre><span style=3D" color:#000000;">{</span></pre>
<pre><span style=3D" color:#c0c0c0;"> </span>uint64_t<span style=3D" color=
:#c0c0c0;"> </span><span style=3D" color:#000000;">a</span><span style=3D" =
color:#000000;">=3D~</span><span style=3D" color:#000080;">0</span><span st=
yle=3D" color:#000000;">;</span></pre>
<pre><span style=3D" color:#c0c0c0;"> </span>set_overflow_flag<span style=
=3D" color:#000000;">(</span><span style=3D" color:#808000;">false</span><s=
pan style=3D" color:#000000;">);</span><span style=3D" color:#008000;">//hi=
nt</span><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#008=
000;">to</span><span style=3D" color:#c0c0c0;"> </span><span style=3D" colo=
r:#008000;">compiler/optimizer</span></pre>
<pre><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#000000=
;">a</span><span style=3D" color:#000000;">+=3D</span><span style=3D" color=
:#000080;">5</span><span style=3D" color:#000000;">;</span></pre>
<pre><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#000080=
;">assert</span><span style=3D" color:#000000;">(</span>overflow_flag<span =
style=3D" color:#000000;">());</span></pre>
<pre><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#000080=
;">assert</span><span style=3D" color:#000000;">(</span><span style=3D" col=
or:#000000;">a</span><span style=3D" color:#000000;">=3D=3D</span><span sty=
le=3D" color:#000080;">4</span><span style=3D" color:#000000;">);</span></p=
re>
<pre><span style=3D" color:#c0c0c0;"> </span><span style=3D" color:#808000=
;">return</span><span style=3D" color:#c0c0c0;"> </span><span style=3D" col=
or:#000080;">0</span><span style=3D" color:#000000;">;</span></pre>
<pre><span style=3D" color:#000000;">}</span><!--EndFragment--></pre><pre><=
span style=3D" color:#000000;"><br></span></pre><pre>//Variant 2:</pre><pre=
>// to extend the operators syntax on integral built-in types to allow to c=
apture the extra <span style=3D"font-family: Arial, Helvetica, sans-se=
rif;">overflow/carry </span><span style=3D"font-family: Arial, Helvetica, s=
ans-serif;">flag bit (bool) </span></pre><pre><span style=3D"font-family: A=
rial, Helvetica, sans-serif;">// or higher word in multiplications</span></=
pre><pre><font face=3D"Arial, Helvetica, sans-serif">// [] for overflow(hi =
part)/ in unsigned arithmetics , {} for carry in signed arithmetics</font>=
</pre><pre><br></pre><pre><span style=3D"font-family: Arial, Helvetica, san=
s-serif;">uint64_t</span><span style=3D"font-family: Arial, Helvetica, sans=
-serif; color: rgb(192, 192, 192);"> </span><span style=3D"font-family: Ari=
al, Helvetica, sans-serif; color: rgb(0, 0, 0);">a</span><span style=3D"fon=
t-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0);">=3D~</span><s=
pan style=3D"font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 12=
8);">0</span><span style=3D"font-family: Arial, Helvetica, sans-serif; colo=
r: rgb(0, 0, 0);">;</span><br></pre><pre><span style=3D"color: rgb(0, 0, 0)=
;">uint64_t b=3D0;</span></pre><pre><span style=3D"color: rgb(0, 0, 0);">bo=
ol overflow;</span></pre><pre><span style=3D"color: rgb(0, 0, 0);">[overflo=
w]b=3Da+2;</span></pre><pre>assert(b=3D=3D1);</pre><pre>assert(of);</pre><p=
re><br></pre><pre>//multiplication:</pre><pre><span style=3D"font-family: A=
rial, Helvetica, sans-serif;">uint64_t</span><span style=3D"font-family: Ar=
ial, Helvetica, sans-serif; color: rgb(192, 192, 192);"> </span><span style=
=3D"font-family: Arial, Helvetica, sans-serif; color: rgb(0, 0, 0);">a=3D1&=
lt;<63;</span></pre><pre><span style=3D"font-family: Arial, Helvetica, s=
ans-serif;">uint64_t</span><span style=3D"font-family: Arial, Helvetica, sa=
ns-serif; color: rgb(192, 192, 192);"> </span><span style=3D"font-family: A=
rial, Helvetica, sans-serif;"><font color=3D"#000000">b=3D1<<1;</font=
></span></pre><pre><span style=3D"font-family: Arial, Helvetica, sans-serif=
;">uint64_t</span><span style=3D"font-family: Arial, Helvetica, sans-serif;=
color: rgb(192, 192, 192);"> </span><span style=3D"font-family: Arial, Hel=
vetica, sans-serif;"><font color=3D"#000000">c;</font></span></pre><pre><sp=
an style=3D"font-family: Arial, Helvetica, sans-serif;">uint64_t</span><spa=
n style=3D"font-family: Arial, Helvetica, sans-serif; color: rgb(192, 192, =
192);"> </span><span style=3D"font-family: Arial, Helvetica, sans-serif;"><=
font color=3D"#000000">d;</font></span></pre><pre><span style=3D"font-famil=
y: Arial, Helvetica, sans-serif;"><font color=3D"#000000">[c]d=3Da*b;</font=
></span></pre><pre><br></pre><pre>I am interested in a feedback if this wou=
ld be a useful extension and if there are any potential problems.</pre=
><pre>Also can someone formalize the proposal?</pre><pre><br></pre><pre>Mar=
ian Klein</pre></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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_2013_905066364.1433373368722--
------=_Part_2012_1897229860.1433373368721--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 3 Jun 2015 18:02:44 -0700
Raw View
--001a11c204faaaaac20517a6bb41
Content-Type: text/plain; charset=UTF-8
On Wed, Jun 3, 2015 at 4:16 PM, Marian Klein <mkleinsoft@gmail.com> wrote:
> Hi folks
>
>
> Just preliminary proposal:
>
>
> Compiler gcc offers built-in function to do basic arithmetic operations with overflow/carry.
>
> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>
>
> It would be great if the C++ language itself supported this operations even for arithmetic operators for better readability
>
> and better optimization.
>
>
> There are two possibilities I can think of:
>
> //Variant 1: using global functions to set/get flags after/before arithmetic operations.
>
> #include <inttypes.h>
>
> #include <assert.h>
>
> #include <flags>
>
>
> //void set_overflow_flag(bool b);
>
> //bool overflow_flag();
>
>
> int main()
>
> {
>
> uint64_t a=~0;
>
> set_overflow_flag(false);//hint to compiler/optimizer
>
> a+=5;
>
> assert(overflow_flag());
>
>
This variant stands no chance of succeeding. Don't try to define the
undefined behavior here.
assert(a==4);
>
> return 0;
>
> }
>
>
> //Variant 2:
>
> // to extend the operators syntax on integral built-in types to allow to capture the extra overflow/carry flag bit (bool)
>
> // or higher word in multiplications
>
> // [] for overflow(hi part)/ in unsigned arithmetics , {} for carry in signed arithmetics
>
>
> uint64_t a=~0;
>
> uint64_t b=0;
>
> bool overflow;
>
> [overflow]b=a+2;
>
> assert(b==1);
>
> assert(of);
>
>
> //multiplication:
>
> uint64_t a=1<<63;
>
> uint64_t b=1<<1;
>
> uint64_t c;
>
> uint64_t d;
>
> [c]d=a*b;
>
>
> I am interested in a feedback if this would be a useful extension and if there are any potential problems.
>
>
Have you considered providing a library interface to this functionality
instead of adding new core language syntax for it?
> Also can someone formalize the proposal?
>
>
> Marian Klein
>
> --
>
> ---
> 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/.
>
--
---
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/.
--001a11c204faaaaac20517a6bb41
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 W=
ed, Jun 3, 2015 at 4:16 PM, Marian Klein <span dir=3D"ltr"><<a href=3D"m=
ailto:mkleinsoft@gmail.com" target=3D"_blank">mkleinsoft@gmail.com</a>><=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">
<pre>Hi folks</pre><pre><br></pre><pre>Just preliminary proposal:</pre><pre=
><br></pre><pre>Compiler gcc offers built-in function to do basic arithmeti=
c operations with overflow/carry. </pre><pre><span style=3D"color:rgb(0,128=
,0)"><a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtin=
s.html" target=3D"_blank">https://gcc.gnu.org/onlinedocs/gcc/Integer-Overfl=
ow-Builtins.html</a></span></pre><pre><br></pre><pre>It would be great if t=
he C++ language itself supported this operations even for arithmetic operat=
ors for better readability</pre><pre>and better optimization.</pre><pre><br=
></pre><pre>There are two possibilities I can think of:</pre><pre>//Variant=
1: using global functions to set/get flags after/before arithmetic operati=
ons.</pre><pre><span style=3D"color:#000080">#include</span><span style=3D"=
color:#c0c0c0"> </span><span style=3D"color:#008000"><inttypes.h></sp=
an></pre>
<pre><span style=3D"color:#000080">#include</span><span style=3D"color:#c0c=
0c0"> </span><span style=3D"color:#008000"><assert.h></span></pre>
<pre><span style=3D"color:#000080">#include</span><span style=3D"color:#c0c=
0c0"> </span><span style=3D"color:#008000"><flags></span></pre>
<pre><br></pre>
<pre><span style=3D"color:#008000">//void</span><span style=3D"color:#c0c0c=
0"> </span><span style=3D"color:#008000">set_overflow_flag(bool</span><span=
style=3D"color:#c0c0c0"> </span><span style=3D"color:#008000">b);</span></=
pre>
<pre><span style=3D"color:#008000">//bool</span><span style=3D"color:#c0c0c=
0"> </span><span style=3D"color:#008000">overflow_flag();</span></pre>
<pre><br></pre>
<pre><span style=3D"color:#808000">int</span><span style=3D"color:#c0c0c0">=
</span><span style=3D"color:#000000">main</span><span style=3D"color:#0000=
00">()</span></pre>
<pre><span style=3D"color:#000000">{</span></pre>
<pre><span style=3D"color:#c0c0c0"> </span>uint64_t<span style=3D"color:#c=
0c0c0"> </span><span style=3D"color:#000000">a</span><span style=3D"color:#=
000000">=3D~</span><span style=3D"color:#000080">0</span><span style=3D"col=
or:#000000">;</span></pre>
<pre><span style=3D"color:#c0c0c0"> </span>set_overflow_flag<span style=3D=
"color:#000000">(</span><span style=3D"color:#808000">false</span><span sty=
le=3D"color:#000000">);</span><span style=3D"color:#008000">//hint</span><s=
pan style=3D"color:#c0c0c0"> </span><span style=3D"color:#008000">to</span>=
<span style=3D"color:#c0c0c0"> </span><span style=3D"color:#008000">compile=
r/optimizer</span></pre>
<pre><span style=3D"color:#c0c0c0"> </span><span style=3D"color:#000000">a=
</span><span style=3D"color:#000000">+=3D</span><span style=3D"color:#00008=
0">5</span><span style=3D"color:#000000">;</span></pre>
<pre><span style=3D"color:#c0c0c0"> </span><span style=3D"color:#000080">a=
ssert</span><span style=3D"color:#000000">(</span>overflow_flag<span style=
=3D"color:#000000">());</span></pre></div></blockquote><div><br></div><div>=
This variant stands no chance of succeeding. Don't try to define the un=
defined behavior here.</div><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"ltr">
<pre><span style=3D"color:#c0c0c0"> </span><span style=3D"color:#000080">a=
ssert</span><span style=3D"color:#000000">(</span><span style=3D"color:#000=
000">a</span><span style=3D"color:#000000">=3D=3D</span><span style=3D"colo=
r:#000080">4</span><span style=3D"color:#000000">);</span></pre>
<pre><span style=3D"color:#c0c0c0"> </span><span style=3D"color:#808000">r=
eturn</span><span style=3D"color:#c0c0c0"> </span><span style=3D"color:#000=
080">0</span><span style=3D"color:#000000">;</span></pre>
<pre><span style=3D"color:#000000">}</span></pre><pre><span style=3D"color:=
#000000"><br></span></pre><pre>//Variant 2:</pre><pre>// to extend the oper=
ators syntax on integral built-in types to allow to capture the extra=C2=A0=
<span style=3D"font-family:Arial,Helvetica,sans-serif">overflow/carry </spa=
n><span style=3D"font-family:Arial,Helvetica,sans-serif">flag bit (bool) </=
span></pre><pre><span style=3D"font-family:Arial,Helvetica,sans-serif">// o=
r higher word in multiplications</span></pre><pre><font face=3D"Arial, Helv=
etica, sans-serif">// [] for overflow(hi part)/ in unsigned arithmetics , =
{} for carry in signed arithmetics</font></pre><pre><br></pre><pre><span st=
yle=3D"font-family:Arial,Helvetica,sans-serif">uint64_t</span><span style=
=3D"font-family:Arial,Helvetica,sans-serif;color:rgb(192,192,192)"> </span>=
<span style=3D"font-family:Arial,Helvetica,sans-serif;color:rgb(0,0,0)">a</=
span><span style=3D"font-family:Arial,Helvetica,sans-serif;color:rgb(0,0,0)=
">=3D~</span><span style=3D"font-family:Arial,Helvetica,sans-serif;color:rg=
b(0,0,128)">0</span><span style=3D"font-family:Arial,Helvetica,sans-serif;c=
olor:rgb(0,0,0)">;</span><br></pre><pre><span style=3D"color:rgb(0,0,0)">ui=
nt64_t b=3D0;</span></pre><pre><span style=3D"color:rgb(0,0,0)">bool overfl=
ow;</span></pre><pre><span style=3D"color:rgb(0,0,0)">[overflow]b=3Da+2;</s=
pan></pre><pre>assert(b=3D=3D1);</pre><pre>assert(of);</pre><pre><br></pre>=
<pre>//multiplication:</pre><pre><span style=3D"font-family:Arial,Helvetica=
,sans-serif">uint64_t</span><span style=3D"font-family:Arial,Helvetica,sans=
-serif;color:rgb(192,192,192)"> </span><span style=3D"font-family:Arial,Hel=
vetica,sans-serif;color:rgb(0,0,0)">a=3D1<<63;</span></pre><pre><span=
style=3D"font-family:Arial,Helvetica,sans-serif">uint64_t</span><span styl=
e=3D"font-family:Arial,Helvetica,sans-serif;color:rgb(192,192,192)"> </span=
><span style=3D"font-family:Arial,Helvetica,sans-serif"><font color=3D"#000=
000">b=3D1<<1;</font></span></pre><pre><span style=3D"font-family:Ari=
al,Helvetica,sans-serif">uint64_t</span><span style=3D"font-family:Arial,He=
lvetica,sans-serif;color:rgb(192,192,192)"> </span><span style=3D"font-fami=
ly:Arial,Helvetica,sans-serif"><font color=3D"#000000">c;</font></span></pr=
e><pre><span style=3D"font-family:Arial,Helvetica,sans-serif">uint64_t</spa=
n><span style=3D"font-family:Arial,Helvetica,sans-serif;color:rgb(192,192,1=
92)"> </span><span style=3D"font-family:Arial,Helvetica,sans-serif"><font c=
olor=3D"#000000">d;</font></span></pre><pre><span style=3D"font-family:Aria=
l,Helvetica,sans-serif"><font color=3D"#000000">[c]d=3Da*b;</font></span></=
pre><pre><br></pre><pre>I am interested in a feedback if this would be a us=
eful extension and if there are any potential=C2=A0problems.</pre></div></b=
lockquote><div><br></div><div>Have you considered providing a library inter=
face to this functionality instead of adding new core language syntax for i=
t?</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><p=
re>Also can someone formalize the proposal?</pre><span class=3D"HOEnZb"><fo=
nt color=3D"#888888"><pre><br></pre><pre>Marian Klein</pre></font></span></=
div><span class=3D"HOEnZb"><font color=3D"#888888">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></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" 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 />
--001a11c204faaaaac20517a6bb41--
.
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Thu, 4 Jun 2015 03:12:42 +0100
Raw View
Hi Richard.
The library based standard would be something equivalent to what is
already available in each respective environment (and implemented
differently.) I provided a link to gcc:
https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
But the whole point is to have a clearer and shorter and more powerful
standardized code , it is possible to do only with core syntax
extension.
(It is similar to situation with lambda functions. In C++03 if you
wanted do create a complex function objects in place you had to do
nasty complex nesting with bind1st, bind2st logical_and logical_or by
using STL. in C++11 it is solved nicely with lambda functions. It is
much more elegant and simpler solution but it required the change in
the core language.)
One more example for advanced overflow arithmetics:
One bit overflow is sufficient if you add two variables only.
Especially the multiplication thing is useful.It shows one bit
overflow is not enough.
Example: You want to add many variables you want to accumulate
overflow bits , with complex arithmetics you want
uint64_t sum_lo,sum_hi,a,b,c;
[sum_hi]sum_lo=a+b+c;
Example: You want to do a safe sumation of many integer values, we can
chain the higher order of the total:
sum_hi=sum_lo=0;
uint64_t sum_hi2=0;
uint64 func(uint64);
std::vector<uint64_t> vect;
//assume vect is populated
uint64 cnt=0;
for ( auto x: vect)
{
[sum_hi2][sum_hi]sum_lo+= func(x);//we can chain the higher parts
of value [sum_hi2][sum_hi]
if (sum_hi2)
{
std::cout << "The total of values has become too big to handle
at the element number " << cnt << std::endl;
break;
}
cnt++;
}
This language extension would allow to implement easily and
efficiently classes representing the arithmetic types with arbitrary
(unbound) width/ precision.
Best regards.
On 4 June 2015 at 02:02, Richard Smith <richard@metafoo.co.uk> wrote:
> On Wed, Jun 3, 2015 at 4:16 PM, Marian Klein <mkleinsoft@gmail.com> wrote:
>>
>> Hi folks
>>
>>
>> Just preliminary proposal:
>>
>>
>> Compiler gcc offers built-in function to do basic arithmetic operations
>> with overflow/carry.
>>
>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>
>>
>> It would be great if the C++ language itself supported this operations
>> even for arithmetic operators for better readability
>>
>> and better optimization.
>>
>>
>> There are two possibilities I can think of:
>>
>> //Variant 1: using global functions to set/get flags after/before
>> arithmetic operations.
>>
>> #include <inttypes.h>
>>
>> #include <assert.h>
>>
>> #include <flags>
>>
>>
>> //void set_overflow_flag(bool b);
>>
>> //bool overflow_flag();
>>
>>
>> int main()
>>
>> {
>>
>> uint64_t a=~0;
>>
>> set_overflow_flag(false);//hint to compiler/optimizer
>>
>> a+=5;
>>
>> assert(overflow_flag());
>
>
> This variant stands no chance of succeeding. Don't try to define the
> undefined behavior here.
>
>> assert(a==4);
>>
>> return 0;
>>
>> }
>>
>>
>> //Variant 2:
>>
>> // to extend the operators syntax on integral built-in types to allow to
>> capture the extra overflow/carry flag bit (bool)
>>
>> // or higher word in multiplications
>>
>> // [] for overflow(hi part)/ in unsigned arithmetics , {} for carry in
>> signed arithmetics
>>
>>
>> uint64_t a=~0;
>>
>> uint64_t b=0;
>>
>> bool overflow;
>>
>> [overflow]b=a+2;
>>
>> assert(b==1);
>>
>> assert(of);
>>
>>
>> //multiplication:
>>
>> uint64_t a=1<<63;
>>
>> uint64_t b=1<<1;
>>
>> uint64_t c;
>>
>> uint64_t d;
>>
>> [c]d=a*b;
>>
>>
>> I am interested in a feedback if this would be a useful extension and if
>> there are any potential problems.
>
>
> Have you considered providing a library interface to this functionality
> instead of adding new core language syntax for it?
>
>>
>> Also can someone formalize the proposal?
>>
>>
>> Marian Klein
>>
>> --
>>
>> ---
>> 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/.
>
>
> --
>
> ---
> 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/.
--
---
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: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 3 Jun 2015 20:25:13 -0700 (PDT)
Raw View
------=_Part_2113_1329684887.1433388313290
Content-Type: multipart/alternative;
boundary="----=_Part_2114_1299065127.1433388313290"
------=_Part_2114_1299065127.1433388313290
Content-Type: text/plain; charset=UTF-8
On Wednesday, June 3, 2015 at 10:12:43 PM UTC-4, Marian Klein wrote:
>
> Hi Richard.
> The library based standard would be something equivalent to what is
> already available in each respective environment (and implemented
> differently.) I provided a link to gcc:
> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>
> But the whole point is to have a clearer and shorter and more powerful
> standardized code , it is possible to do only with core syntax
> extension.
>
> (It is similar to situation with lambda functions. In C++03 if you
> wanted do create a complex function objects in place you had to do
> nasty complex nesting with bind1st, bind2st logical_and logical_or by
> using STL. in C++11 it is solved nicely with lambda functions. It is
> much more elegant and simpler solution but it required the change in
> the core language.)
>
It's a similar situation, to be certain. But you can't seriously believe
that these operators are *nearly* as universally useful as lambda functions.
This is best handled by the library because of its narrow range of use.
Most people just don't care about overflows. You might argue that more
people should, but that's the standard we have right now. And adding a
language change for something that has such a relatively narrow potential
user-base is... unlikely, bordering on wishful thinking.
--
---
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_2114_1299065127.1433388313290
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, June 3, 2015 at 10:12:43 PM UTC-4, M=
arian Klein wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;marg=
in-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi Richard.
<br>The library based standard would be something equivalent to what is
<br>already available in each respective environment (and implemented
<br>differently.) I provided a link to gcc:
<br><a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins=
..html" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https=
://www.google.com/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FIn=
teger-Overflow-Builtins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwx=
Xm6uVuUz-BV2oZaEQ';return true;" onclick=3D"this.href=3D'https://www.google=
..com/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FInteger-Overflo=
w-Builtins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwxXm6uVuUz-BV2o=
ZaEQ';return true;">https://gcc.gnu.org/<wbr>onlinedocs/gcc/Integer-<wbr>Ov=
erflow-Builtins.html</a>
<br>
<br>But the whole point is to have a clearer and shorter and more powerful
<br>standardized code , it is possible to do only with core syntax
<br>extension.
<br>
<br>(It is similar to situation with lambda functions. In C++03 if you
<br>wanted do create a complex function objects in place you had to do
<br>nasty complex nesting with bind1st, bind2st logical_and logical_o=
r by
<br>using STL. in C++11 it is solved nicely with lambda functions. &n=
bsp;It is
<br>much more elegant and simpler solution but it required the change in
<br>the core language.)
<br></blockquote><div><br>It's a similar situation, to be certain. But you =
can't seriously believe that these operators are <i>nearly</i> as universal=
ly useful as lambda functions.<br><br>This is best handled by the library b=
ecause of its narrow range of use. Most people just don't care about overfl=
ows. You might argue that more people should, but that's the standard we ha=
ve right now. And adding a language change for something that has such a re=
latively narrow potential user-base is... unlikely, bordering on wishful th=
inking.</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" 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_2114_1299065127.1433388313290--
------=_Part_2113_1329684887.1433388313290--
.
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Thu, 4 Jun 2015 11:44:37 +0100
Raw View
Hi Nicol
They are very useful , it is about safety and trust. Just because the
language uses by default the modular aritmetics with no flagging for
overflow, you can NOT trust any result of any arithmetic operation
over integers without previous checking. Maybe it is sufficient only
throwing an exception and/or using C++11 attributes ([[ ]] ) so you
can switch on/off throwing for performance reason if the most people
don't care, so it does not interfere with the program flow for the
most people.
There are industries where they care about trust a lot, science, video
processing, aviation industry and they can do it only at the cost of
additional overhead or in assembler (hence not portable).
This exception proposal is not so much disruptive into existing core
language syntax and it is implementable in compilers quickly.
uint64_t sum(vector<uint64_t>& vect) [[throw_on_overflow]]
throw(std::arithmetic_overflow)
{
uint64_t total=0;
for(auto x: vect)
total+=x [[throw_on_overflow]];
return total;
}
vector<uint64_t>& vect;
//assume vect is populated
uint64_t total=0;
try{
total=sum(vect);
}catch(std::arithmetic_overflow& of)
{
std::cout << "overflow: operation:" << of.what() << " operand1="
<< of.operand(0) << " operand2="<< of.operand(1)
<< " address of operand1=" << of.addr_operand(0) << " add
operand2=" of.operand(1) << std::endl;
}
//similar for multiplication
uint64_t hi_mult=0,mult,a,b;
try {
mult [[throw_on_overflow]]=a*b ;// mult is filled even if overflow
and exception is thrown
} catch (std::multiplication_overflow& mo)
{
std::cout << " hi_mult=" << mo.hi_word() << std::endl;
}
Best regards
Marian
On 4 June 2015 at 04:25, Nicol Bolas <jmckesson@gmail.com> wrote:
>
>
> On Wednesday, June 3, 2015 at 10:12:43 PM UTC-4, Marian Klein wrote:
>>
>> Hi Richard.
>> The library based standard would be something equivalent to what is
>> already available in each respective environment (and implemented
>> differently.) I provided a link to gcc:
>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>
>> But the whole point is to have a clearer and shorter and more powerful
>> standardized code , it is possible to do only with core syntax
>> extension.
>>
>> (It is similar to situation with lambda functions. In C++03 if you
>> wanted do create a complex function objects in place you had to do
>> nasty complex nesting with bind1st, bind2st logical_and logical_or by
>> using STL. in C++11 it is solved nicely with lambda functions. It is
>> much more elegant and simpler solution but it required the change in
>> the core language.)
>
>
> It's a similar situation, to be certain. But you can't seriously believe
> that these operators are nearly as universally useful as lambda functions.
>
> This is best handled by the library because of its narrow range of use. Most
> people just don't care about overflows. You might argue that more people
> should, but that's the standard we have right now. And adding a language
> change for something that has such a relatively narrow potential user-base
> is... unlikely, bordering on wishful thinking.
>
> --
>
> ---
> 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/.
--
---
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: "dgutson ." <danielgutson@gmail.com>
Date: Thu, 4 Jun 2015 08:19:46 -0300
Raw View
--001a11c22d1065d5b70517af5ade
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
El 4/6/2015 7:44, "Marian Klein" <mkleinsoft@gmail.com> escribi=C3=B3:
>
> Hi Nicol
>
> They are very useful , it is about safety and trust. Just because the
> language uses by default the modular aritmetics with no flagging for
> overflow, you can NOT trust any result of any arithmetic operation
> over integers without previous checking. Maybe it is sufficient only
> throwing an exception and/or using C++11 attributes ([[ ]] ) so you
> can switch on/off throwing for performance reason if the most people
> don't care, so it does not interfere with the program flow for the
> most people.
You are still not providing a strong argument against the library version,
specially considering the opposition you got and will get as a core
language feature (which is, believe me, a dead end for this proposal).
So my suggestion is: if you are serious about solving the problem (rather
than pursuing a particular solution), go and get those built-ins, wrap them
in nice template classes with overloaded operators, and come back with a
working prototype. Write a proposal stating what the problem is, why it is
a problen, how people is working around it nowadays, and show your working
library solution as a proposed addition to the STL.
If you happen to like my suggestion, then consider also a throwing and non
throwing version for deeply embedded systems (so it can be used e.g inside
an interrupt handler).
Daniel.
> There are industries where they care about trust a lot, science, video
> processing, aviation industry and they can do it only at the cost of
> additional overhead or in assembler (hence not portable).
> This exception proposal is not so much disruptive into existing core
> language syntax and it is implementable in compilers quickly.
>
> uint64_t sum(vector<uint64_t>& vect) [[throw_on_overflow]]
> throw(std::arithmetic_overflow)
> {
> uint64_t total=3D0;
> for(auto x: vect)
> total+=3Dx [[throw_on_overflow]];
> return total;
> }
>
> vector<uint64_t>& vect;
> //assume vect is populated
> uint64_t total=3D0;
> try{
> total=3Dsum(vect);
> }catch(std::arithmetic_overflow& of)
> {
> std::cout << "overflow: operation:" << of.what() << " operand1=3D"
> << of.operand(0) << " operand2=3D"<< of.operand(1)
> << " address of operand1=3D" << of.addr_operand(0) << " add
> operand2=3D" of.operand(1) << std::endl;
> }
>
> //similar for multiplication
> uint64_t hi_mult=3D0,mult,a,b;
> try {
> mult [[throw_on_overflow]]=3Da*b ;// mult is filled even if overflow
> and exception is thrown
> } catch (std::multiplication_overflow& mo)
> {
> std::cout << " hi_mult=3D" << mo.hi_word() << std::endl;
> }
>
> Best regards
>
> Marian
>
> On 4 June 2015 at 04:25, Nicol Bolas <jmckesson@gmail.com> wrote:
> >
> >
> > On Wednesday, June 3, 2015 at 10:12:43 PM UTC-4, Marian Klein wrote:
> >>
> >> Hi Richard.
> >> The library based standard would be something equivalent to what is
> >> already available in each respective environment (and implemented
> >> differently.) I provided a link to gcc:
> >> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
> >>
> >> But the whole point is to have a clearer and shorter and more powerful
> >> standardized code , it is possible to do only with core syntax
> >> extension.
> >>
> >> (It is similar to situation with lambda functions. In C++03 if you
> >> wanted do create a complex function objects in place you had to do
> >> nasty complex nesting with bind1st, bind2st logical_and logical_or by
> >> using STL. in C++11 it is solved nicely with lambda functions. It is
> >> much more elegant and simpler solution but it required the change in
> >> the core language.)
> >
> >
> > It's a similar situation, to be certain. But you can't seriously believ=
e
> > that these operators are nearly as universally useful as lambda
functions.
> >
> > This is best handled by the library because of its narrow range of use.
Most
> > people just don't care about overflows. You might argue that more peopl=
e
> > should, but that's the standard we have right now. And adding a languag=
e
> > change for something that has such a relatively narrow potential
user-base
> > is... unlikely, bordering on wishful thinking.
> >
> > --
> >
> > ---
> > 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/.
>
> --
>
> ---
> 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/.
--=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/.
--001a11c22d1065d5b70517af5ade
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr"><br>
El 4/6/2015 7:44, "Marian Klein" <<a href=3D"mailto:mkleinsoft=
@gmail.com">mkleinsoft@gmail.com</a>> escribi=C3=B3:<br>
><br>
> Hi Nicol<br>
><br>
> They are very useful , it is about safety and trust. Just because the<=
br>
> language uses by default the modular aritmetics with no flagging for<b=
r>
> overflow, you can NOT trust any result of any arithmetic operation<br>
> over integers without previous checking.=C2=A0 Maybe it is sufficient =
only<br>
> throwing an exception and/or using C++11 attributes ([[ ]] ) so you<br=
>
> can switch on/off throwing for performance reason if the most people<b=
r>
> don't=C2=A0 care, so it does not interfere with the program flow f=
or the<br>
> most people.</p>
<p dir=3D"ltr">You are still not providing a strong argument against the li=
brary version, specially considering the opposition you got and will get as=
a core language feature (which is, believe me, a dead end for this proposa=
l).<br>
So my suggestion is: if you are serious about solving the problem (rather t=
han pursuing a particular solution), go and get those built-ins, wrap them =
in nice template=C2=A0 classes with overloaded operators, and come back wit=
h a working prototype. Write a proposal stating what the problem is, why it=
is a problen, how people is working around it nowadays, and show your work=
ing library solution as a proposed addition to the STL.</p>
<p dir=3D"ltr">If you happen to like my suggestion, then consider also a th=
rowing and non throwing version for deeply embedded systems (so it can be u=
sed e.g=C2=A0 inside an interrupt handler).</p>
<p dir=3D"ltr">=C2=A0=C2=A0=C2=A0 Daniel.<br></p>
<p dir=3D"ltr">> There are industries where they care about trust a lot,=
science, video<br>
> processing, aviation industry and they can do it only at the cost of<b=
r>
> additional overhead or in assembler (hence not portable).<br>
> This exception proposal is not so much disruptive into existing core<b=
r>
> language syntax and it is implementable in compilers quickly.<br>
><br>
> uint64_t sum(vector<uint64_t>& vect) [[throw_on_overflow]]<b=
r>
> throw(std::arithmetic_overflow)<br>
> {<br>
> =C2=A0 uint64_t total=3D0;<br>
> =C2=A0 for(auto x: vect)<br>
> =C2=A0 =C2=A0 =C2=A0total+=3Dx [[throw_on_overflow]];<br>
> =C2=A0 return total;<br>
> }<br>
><br>
> vector<uint64_t>& vect;<br>
> //assume vect is populated<br>
> uint64_t total=3D0;<br>
> try{<br>
> =C2=A0 =C2=A0total=3Dsum(vect);<br>
> }catch(std::arithmetic_overflow& of)<br>
> {<br>
> =C2=A0 =C2=A0std::cout << "overflow: operation:" <&=
lt; of.what()=C2=A0 << " operand1=3D"<br>
> << of.operand(0) << " operand2=3D"<< of.op=
erand(1)<br>
> =C2=A0 =C2=A0 << "=C2=A0 address of operand1=3D" <&=
lt; of.addr_operand(0)=C2=A0 << " add<br>
> operand2=3D" of.operand(1) << std::endl;<br>
> }<br>
><br>
> //similar for multiplication<br>
> uint64_t hi_mult=3D0,mult,a,b;<br>
> try {<br>
> =C2=A0 mult [[throw_on_overflow]]=3Da*b ;// mult is filled even if ove=
rflow<br>
> and exception is thrown<br>
> } catch (std::multiplication_overflow& mo)<br>
> {<br>
> =C2=A0 std::cout << " hi_mult=3D" << mo.hi_word(=
) << std::endl;<br>
> }<br>
><br>
> Best regards<br>
><br>
> Marian<br>
><br>
> On 4 June 2015 at 04:25, Nicol Bolas <<a href=3D"mailto:jmckesson@g=
mail.com">jmckesson@gmail.com</a>> wrote:<br>
> ><br>
> ><br>
> > On Wednesday, June 3, 2015 at 10:12:43 PM UTC-4, Marian Klein wro=
te:<br>
> >><br>
> >> Hi Richard.<br>
> >> The library based standard would be something equivalent to w=
hat is<br>
> >> already available in each respective environment (and impleme=
nted<br>
> >> differently.) I provided a link to gcc:<br>
> >> <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflo=
w-Builtins.html">https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builti=
ns.html</a><br>
> >><br>
> >> But the whole point is to have a clearer and shorter and more=
powerful<br>
> >> standardized code , it is possible to do only with core synta=
x<br>
> >> extension.<br>
> >><br>
> >> (It is similar to situation with lambda functions. In C++03 i=
f you<br>
> >> wanted do create a complex function objects in place you had =
to do<br>
> >> nasty complex nesting with bind1st, bind2st=C2=A0 logical_and=
logical_or by<br>
> >> using STL.=C2=A0 in C++11 it is solved nicely with lambda fun=
ctions.=C2=A0 It is<br>
> >> much more elegant and simpler solution but it required the ch=
ange in<br>
> >> the core language.)<br>
> ><br>
> ><br>
> > It's a similar situation, to be certain. But you can't se=
riously believe<br>
> > that these operators are nearly as universally useful as lambda f=
unctions.<br>
> ><br>
> > This is best handled by the library because of its narrow range o=
f use. Most<br>
> > people just don't care about overflows. You might argue that =
more people<br>
> > should, but that's the standard we have right now. And adding=
a language<br>
> > change for something that has such a relatively narrow potential =
user-base<br>
> > is... unlikely, bordering on wishful thinking.<br>
> ><br>
> > --<br>
> ><br>
> > ---<br>
> > You received this message because you are subscribed to the Googl=
e Groups<br>
> > "ISO C++ Standard - Future Proposals" group.<br>
> > To unsubscribe from this group and stop receiving emails from it,=
send an<br>
> > email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org=
">std-proposals+unsubscribe@isocpp.org</a>.<br>
> > To post to this group, send email to <a href=3D"mailto:std-propos=
als@isocpp.org">std-proposals@isocpp.org</a>.<br>
> > Visit this group at<br>
> > <a href=3D"http://groups.google.com/a/isocpp.org/group/std-propos=
als/">http://groups.google.com/a/isocpp.org/group/std-proposals/</a>.<br>
><br>
> --<br>
><br>
> ---<br>
> You received this message because you are subscribed to the Google Gro=
ups "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this group and stop receiving emails from it, send=
an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/g=
roup/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-propos=
als/</a>.<br>
</p>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--001a11c22d1065d5b70517af5ade--
.
Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Thu, 4 Jun 2015 14:32:39 +0300
Raw View
On Thu, Jun 4, 2015 at 2:19 PM, dgutson . <danielgutson@gmail.com> wrote:
>
> El 4/6/2015 7:44, "Marian Klein" <mkleinsoft@gmail.com> escribi=C3=B3:
>>
>> Hi Nicol
>>
>> They are very useful , it is about safety and trust. Just because the
>> language uses by default the modular aritmetics with no flagging for
>> overflow, you can NOT trust any result of any arithmetic operation
>> over integers without previous checking. Maybe it is sufficient only
>> throwing an exception and/or using C++11 attributes ([[ ]] ) so you
>> can switch on/off throwing for performance reason if the most people
>> don't care, so it does not interfere with the program flow for the
>> most people.
>
> You are still not providing a strong argument against the library version=
,
> specially considering the opposition you got and will get as a core langu=
age
> feature (which is, believe me, a dead end for this proposal).
> So my suggestion is: if you are serious about solving the problem (rather
> than pursuing a particular solution), go and get those built-ins, wrap th=
em
> in nice template classes with overloaded operators, and come back with a
> working prototype. Write a proposal stating what the problem is, why it i=
s a
> problen, how people is working around it nowadays, and show your working
> library solution as a proposed addition to the STL.
>
> If you happen to like my suggestion, then consider also a throwing and no=
n
> throwing version for deeply embedded systems (so it can be used e.g insi=
de
> an interrupt handler).
I'll add that saturating the result on overflow is also a possible and
often desired behavior. A absolutely agree that this problem is best
solved with a policy-based library.
--=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/.
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Thu, 4 Jun 2015 13:10:02 -0700
Raw View
--001a113d5256bca4630517b6c2b2
Content-Type: text/plain; charset=UTF-8
On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein <mkleinsoft@gmail.com> wrote:
> Hi Richard.
> The library based standard would be something equivalent to what is
> already available in each respective environment (and implemented
> differently.) I provided a link to gcc:
> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>
> But the whole point is to have a clearer and shorter and more powerful
> standardized code , it is possible to do only with core syntax
> extension.
>
That's not true. The GCC builtins are one possible library interface, but
there are other interfaces that would give a clearer and shorter syntax
while still being a library solution. For instance, something like this is
easy to implement:
// Compute some function with 32-bit wraparound.
int32_t f(wrapping_int32 a, wrapping_int32 b) {
return a * a + b;
}
.... and likewise you can implement a library where this works:
integer<32> a, b;
// ...
integer<33> s = a + b;
if (!s.fits_in<32>()) {
std::cerr << "addition overflowed\n";
return;
}
integer<65> p = a * b;
//...
(It is similar to situation with lambda functions. In C++03 if you
> wanted do create a complex function objects in place you had to do
> nasty complex nesting with bind1st, bind2st logical_and logical_or by
> using STL. in C++11 it is solved nicely with lambda functions. It is
> much more elegant and simpler solution but it required the change in
> the core language.)
>
> One more example for advanced overflow arithmetics:
>
> One bit overflow is sufficient if you add two variables only.
> Especially the multiplication thing is useful.It shows one bit
> overflow is not enough.
> Example: You want to add many variables you want to accumulate
> overflow bits , with complex arithmetics you want
> uint64_t sum_lo,sum_hi,a,b,c;
> [sum_hi]sum_lo=a+b+c;
>
>
> Example: You want to do a safe sumation of many integer values, we can
> chain the higher order of the total:
>
> sum_hi=sum_lo=0;
> uint64_t sum_hi2=0;
>
> uint64 func(uint64);
>
> std::vector<uint64_t> vect;
>
> //assume vect is populated
> uint64 cnt=0;
>
> for ( auto x: vect)
> {
> [sum_hi2][sum_hi]sum_lo+= func(x);//we can chain the higher parts
> of value [sum_hi2][sum_hi]
> if (sum_hi2)
> {
> std::cout << "The total of values has become too big to handle
> at the element number " << cnt << std::endl;
> break;
> }
> cnt++;
> }
>
> This language extension would allow to implement easily and
> efficiently classes representing the arithmetic types with arbitrary
> (unbound) width/ precision.
>
> Best regards.
>
> On 4 June 2015 at 02:02, Richard Smith <richard@metafoo.co.uk> wrote:
> > On Wed, Jun 3, 2015 at 4:16 PM, Marian Klein <mkleinsoft@gmail.com>
> wrote:
> >>
> >> Hi folks
> >>
> >>
> >> Just preliminary proposal:
> >>
> >>
> >> Compiler gcc offers built-in function to do basic arithmetic operations
> >> with overflow/carry.
> >>
> >> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
> >>
> >>
> >> It would be great if the C++ language itself supported this operations
> >> even for arithmetic operators for better readability
> >>
> >> and better optimization.
> >>
> >>
> >> There are two possibilities I can think of:
> >>
> >> //Variant 1: using global functions to set/get flags after/before
> >> arithmetic operations.
> >>
> >> #include <inttypes.h>
> >>
> >> #include <assert.h>
> >>
> >> #include <flags>
> >>
> >>
> >> //void set_overflow_flag(bool b);
> >>
> >> //bool overflow_flag();
> >>
> >>
> >> int main()
> >>
> >> {
> >>
> >> uint64_t a=~0;
> >>
> >> set_overflow_flag(false);//hint to compiler/optimizer
> >>
> >> a+=5;
> >>
> >> assert(overflow_flag());
> >
> >
> > This variant stands no chance of succeeding. Don't try to define the
> > undefined behavior here.
> >
> >> assert(a==4);
> >>
> >> return 0;
> >>
> >> }
> >>
> >>
> >> //Variant 2:
> >>
> >> // to extend the operators syntax on integral built-in types to allow to
> >> capture the extra overflow/carry flag bit (bool)
> >>
> >> // or higher word in multiplications
> >>
> >> // [] for overflow(hi part)/ in unsigned arithmetics , {} for carry in
> >> signed arithmetics
> >>
> >>
> >> uint64_t a=~0;
> >>
> >> uint64_t b=0;
> >>
> >> bool overflow;
> >>
> >> [overflow]b=a+2;
> >>
> >> assert(b==1);
> >>
> >> assert(of);
> >>
> >>
> >> //multiplication:
> >>
> >> uint64_t a=1<<63;
> >>
> >> uint64_t b=1<<1;
> >>
> >> uint64_t c;
> >>
> >> uint64_t d;
> >>
> >> [c]d=a*b;
> >>
> >>
> >> I am interested in a feedback if this would be a useful extension and if
> >> there are any potential problems.
> >
> >
> > Have you considered providing a library interface to this functionality
> > instead of adding new core language syntax for it?
> >
> >>
> >> Also can someone formalize the proposal?
> >>
> >>
> >> Marian Klein
> >>
> >> --
> >>
> >> ---
> >> 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/.
> >
> >
> > --
> >
> > ---
> > 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/.
>
> --
>
> ---
> 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/.
>
--
---
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/.
--001a113d5256bca4630517b6c2b2
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 W=
ed, Jun 3, 2015 at 7:12 PM, Marian Klein <span dir=3D"ltr"><<a href=3D"m=
ailto:mkleinsoft@gmail.com" target=3D"_blank">mkleinsoft@gmail.com</a>><=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-l=
eft-style:solid;padding-left:1ex">Hi Richard.<br>
The library based standard would be something equivalent to what is<br>
already available in each respective environment (and implemented<br>
differently.) I provided a link to gcc:<br>
<a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.htm=
l" target=3D"_blank">https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Bu=
iltins.html</a><br>
<br>
But the whole point is to have a clearer and shorter and more powerful<br>
standardized code , it is possible to do only with core syntax<br>
extension.<br></blockquote><div><br></div><div>That's not true. The GCC=
builtins are one possible library interface, but there are other interface=
s that would give a clearer and shorter syntax while still being a library =
solution. For instance, something like this is easy to implement:</div><div=
><br></div><div>// Compute some function with 32-bit wraparound.</div><div>=
int32_t f(wrapping_int32 a, wrapping_int32 b) {</div><div>=C2=A0 return a *=
a + b;</div><div>}</div><div><br></div><div>... and likewise you can imple=
ment a library where this works:</div><div><br></div><div>integer<32>=
a, b;</div><div>// ...<br></div><div>integer<33> s =3D a + b;</div><=
div>if (!s.fits_in<32>()) {</div><div>=C2=A0 std::cerr << "=
;addition overflowed\n";</div><div>=C2=A0 return;</div><div>}</div><di=
v>integer<65> p =3D a * b;<br></div><div>//...</div><div><br></div><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;pad=
ding-left:1ex">
(It is similar to situation with lambda functions. In C++03 if you<br>
wanted do create a complex function objects in place you had to do<br>
nasty complex nesting with bind1st, bind2st=C2=A0 logical_and logical_or by=
<br>
using STL.=C2=A0 in C++11 it is solved nicely with lambda functions.=C2=A0 =
It is<br>
much more elegant and simpler solution but it required the change in<br>
the core language.)<br>
<br>
One more example for advanced overflow arithmetics:<br>
<br>
One bit overflow is sufficient if you add two variables only.<br>
Especially the multiplication thing is useful.It shows one bit<br>
overflow is not enough.<br>
Example:=C2=A0 =C2=A0You want to add many variables you want to accumulate<=
br>
overflow bits , with complex arithmetics you want<br>
uint64_t sum_lo,sum_hi,a,b,c;<br>
[sum_hi]sum_lo=3Da+b+c;<br>
<br>
<br>
Example: You want to do a safe sumation of many integer values, we can<br>
chain the higher order of the total:<br>
<br>
sum_hi=3Dsum_lo=3D0;<br>
uint64_t sum_hi2=3D0;<br>
<br>
uint64 func(uint64);<br>
<br>
std::vector<uint64_t> vect;<br>
<br>
//assume vect is populated<br>
uint64 cnt=3D0;<br>
<br>
for ( auto x: vect)<br>
{<br>
=C2=A0 =C2=A0 =C2=A0[sum_hi2][sum_hi]sum_lo+=3D func(x);//we can chain the =
higher parts<br>
of value=C2=A0 [sum_hi2][sum_hi]<br>
=C2=A0 =C2=A0 =C2=A0if (sum_hi2)<br>
=C2=A0 =C2=A0 =C2=A0{<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 std::cout << "The total of values ha=
s become too big to handle<br>
at the element number " << cnt << std::endl;<br>
=C2=A0 =C2=A0 =C2=A0 =C2=A0 break;<br>
=C2=A0 =C2=A0 =C2=A0}<br>
=C2=A0 =C2=A0 =C2=A0cnt++;<br>
}<br>
<br>
This language extension would allow to implement easily and<br>
efficiently classes representing the arithmetic types with arbitrary<br>
(unbound) width/ precision.<br>
<br>
Best regards.<br>
<div class=3D""><div class=3D"h5"><br>
On 4 June 2015 at 02:02, Richard Smith <<a href=3D"mailto:richard@metafo=
o.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> On Wed, Jun 3, 2015 at 4:16 PM, Marian Klein <<a href=3D"mailto:mkl=
einsoft@gmail.com">mkleinsoft@gmail.com</a>> wrote:<br>
>><br>
>> Hi folks<br>
>><br>
>><br>
>> Just preliminary proposal:<br>
>><br>
>><br>
>> Compiler gcc offers built-in function to do basic arithmetic opera=
tions<br>
>> with overflow/carry.<br>
>><br>
>> <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Bui=
ltins.html" target=3D"_blank">https://gcc.gnu.org/onlinedocs/gcc/Integer-Ov=
erflow-Builtins.html</a><br>
>><br>
>><br>
>> It would be great if the C++ language itself supported this operat=
ions<br>
>> even for arithmetic operators for better readability<br>
>><br>
>> and better optimization.<br>
>><br>
>><br>
>> There are two possibilities I can think of:<br>
>><br>
>> //Variant 1: using global functions to set/get flags after/before<=
br>
>> arithmetic operations.<br>
>><br>
>> #include <inttypes.h><br>
>><br>
>> #include <assert.h><br>
>><br>
>> #include <flags><br>
>><br>
>><br>
>> //void set_overflow_flag(bool b);<br>
>><br>
>> //bool overflow_flag();<br>
>><br>
>><br>
>> int main()<br>
>><br>
>> {<br>
>><br>
>>=C2=A0 =C2=A0uint64_t a=3D~0;<br>
>><br>
>>=C2=A0 =C2=A0set_overflow_flag(false);//hint to compiler/optimizer<=
br>
>><br>
>>=C2=A0 =C2=A0a+=3D5;<br>
>><br>
>>=C2=A0 =C2=A0assert(overflow_flag());<br>
><br>
><br>
> This variant stands no chance of succeeding. Don't try to define t=
he<br>
> undefined behavior here.<br>
><br>
>>=C2=A0 =C2=A0assert(a=3D=3D4);<br>
>><br>
>>=C2=A0 =C2=A0return 0;<br>
>><br>
>> }<br>
>><br>
>><br>
>> //Variant 2:<br>
>><br>
>> // to extend the operators syntax on integral built-in types to al=
low to<br>
>> capture the extra overflow/carry flag bit (bool)<br>
>><br>
>> // or higher word in multiplications<br>
>><br>
>> // [] for overflow(hi part)/ in unsigned arithmetics ,=C2=A0 {} fo=
r carry in<br>
>> signed arithmetics<br>
>><br>
>><br>
>> uint64_t a=3D~0;<br>
>><br>
>> uint64_t b=3D0;<br>
>><br>
>> bool overflow;<br>
>><br>
>> [overflow]b=3Da+2;<br>
>><br>
>> assert(b=3D=3D1);<br>
>><br>
>> assert(of);<br>
>><br>
>><br>
>> //multiplication:<br>
>><br>
>> uint64_t a=3D1<<63;<br>
>><br>
>> uint64_t b=3D1<<1;<br>
>><br>
>> uint64_t c;<br>
>><br>
>> uint64_t d;<br>
>><br>
>> [c]d=3Da*b;<br>
>><br>
>><br>
>> I am interested in a feedback if this would be a useful extension =
and if<br>
>> there are any potential problems.<br>
><br>
><br>
> Have you considered providing a library interface to this functionalit=
y<br>
> instead of adding new core language syntax for it?<br>
><br>
>><br>
>> Also can someone formalize the proposal?<br>
>><br>
>><br>
>> Marian Klein<br>
>><br>
>> --<br>
>><br>
>> ---<br>
>> You received this message because you are subscribed to the Google=
Groups<br>
>> "ISO C++ Standard - Future Proposals" group.<br>
>> To unsubscribe from this group and stop receiving emails from it, =
send an<br>
>> email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org"=
>std-proposals+unsubscribe@isocpp.org</a>.<br>
>> To post to this group, send email to <a href=3D"mailto:std-proposa=
ls@isocpp.org">std-proposals@isocpp.org</a>.<br>
>> Visit this group at<br>
>> <a href=3D"http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/" target=3D"_blank">http://groups.google.com/a/isocpp.org/group/std-prop=
osals/</a>.<br>
><br>
><br>
> --<br>
><br>
> ---<br>
> You received this message because you are subscribed to the Google Gro=
ups<br>
> "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this group and stop receiving emails from it, send=
an<br>
> email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std=
-proposals+unsubscribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at<br>
> <a href=3D"http://groups.google.com/a/isocpp.org/group/std-proposals/"=
target=3D"_blank">http://groups.google.com/a/isocpp.org/group/std-proposal=
s/</a>.<br>
<br>
--<br>
<br>
---<br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-propo=
sals+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/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></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" 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 />
--001a113d5256bca4630517b6c2b2--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Thu, 4 Jun 2015 18:16:53 -0700 (PDT)
Raw View
------=_Part_347_916968410.1433467013111
Content-Type: multipart/alternative;
boundary="----=_Part_348_963266678.1433467013111"
------=_Part_348_963266678.1433467013111
Content-Type: text/plain; charset=UTF-8
On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard Smith wrote:
>
> On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein <mklei...@gmail.com
> <javascript:>> wrote:
>
>> Hi Richard.
>> The library based standard would be something equivalent to what is
>> already available in each respective environment (and implemented
>> differently.) I provided a link to gcc:
>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>
>> But the whole point is to have a clearer and shorter and more powerful
>> standardized code , it is possible to do only with core syntax
>> extension.
>>
>
> That's not true. The GCC builtins are one possible library interface, but
> there are other interfaces that would give a clearer and shorter syntax
> while still being a library solution. For instance, something like this is
> easy to implement:
>
> // Compute some function with 32-bit wraparound.
> int32_t f(wrapping_int32 a, wrapping_int32 b) {
> return a * a + b;
> }
>
> ... and likewise you can implement a library where this works:
>
> integer<32> a, b;
> // ...
> integer<33> s = a + b;
>
If you want to use a generic type like integer<N>, it might be better to
use a function call for this operation to show that its doing something
different than the expected behavior for adding 2 numbers. It will also
allow type deduction to be used
template <size_t N, size_t M>
integer<N > M ? N + 1 : M + 1> add_carry(integer<N> l, integer<M> r);
integer<32> a;
integer<32> b;
auto c = a + b; //decltype(c) is integer<32>
auto d = add_carry(a, b); //decltyp(d)is integer<33>
if(d.carry_flag_set()) { }//Tests the highest bit in the value
You could also write a more specific carrying math integer type that's not
called std::integer. This one could have a carry flag bit semantics on its
operations and a user configurable template policy for how to handle what
you consider errors (e.g. throw, assert, log, etc..).
//In my library header
template <size_t N>
using my_carry_int = std::carry_int<N, std::carry_int_assert>;
--
---
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_348_963266678.1433467013111
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Ric=
hard Smith wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margi=
n-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"l=
tr"><div><div class=3D"gmail_quote">On Wed, Jun 3, 2015 at 7:12 PM, Marian =
Klein <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-o=
bfuscated-mailto=3D"Rm40pbiHkaYJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';return =
true;">mklei...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gma=
il_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-le=
ft-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi Rich=
ard.<br>
The library based standard would be something equivalent to what is<br>
already available in each respective environment (and implemented<br>
differently.) I provided a link to gcc:<br>
<a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.htm=
l" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FIntege=
r-Overflow-Builtins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwxXm6u=
VuUz-BV2oZaEQ';return true;" onclick=3D"this.href=3D'https://www.google.com=
/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FInteger-Overflow-Bu=
iltins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwxXm6uVuUz-BV2oZaEQ=
';return true;">https://gcc.gnu.org/<wbr>onlinedocs/gcc/Integer-<wbr>Overfl=
ow-Builtins.html</a><br>
<br>
But the whole point is to have a clearer and shorter and more powerful<br>
standardized code , it is possible to do only with core syntax<br>
extension.<br></blockquote><div><br></div><div>That's not true. The GCC bui=
ltins are one possible library interface, but there are other interfaces th=
at would give a clearer and shorter syntax while still being a library solu=
tion. For instance, something like this is easy to implement:</div><div><br=
></div><div>// Compute some function with 32-bit wraparound.</div><div>int3=
2_t f(wrapping_int32 a, wrapping_int32 b) {</div><div> return a * a +=
b;</div><div>}</div><div><br></div><div>... and likewise you can implement=
a library where this works:</div><div><br></div><div>integer<32> a, =
b;</div><div>// ...<br></div><div>integer<33> s =3D a + b;</div></div=
></div></div></blockquote><div><br></div><div>If you want to use a generic =
type like integer<N>, it might be better to use a function call for t=
his operation to show that its doing something different than the expected =
behavior for adding 2 numbers. It will also allow type deduction to be used=
</div><div><br></div><div><div class=3D"prettyprint" style=3D"border: 1px s=
olid rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, =
250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span=
style=3D"color: #008;" class=3D"styled-by-prettify">template</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify"><</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify">size_t N</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> size_t M</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>integer</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify">N </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
M </span><span style=3D"color: #660;" class=3D"styled-by-prettify">?</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> N </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #06=
6;" class=3D"styled-by-prettify">1</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">:</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> M </span><span style=3D"color: #660;" class=3D"styled-by-prettify">+=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> add_carry</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">integer</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">N</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> l</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> integer=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify">M</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">></span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> r</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"><br><br>integer</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify"><</span><span style=3D"color: #066;" cl=
ass=3D"styled-by-prettify">32</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">></span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> a</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
integer</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
;</span><span style=3D"color: #066;" class=3D"styled-by-prettify">32</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"><br><br></span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">auto</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> c </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> a </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">+</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> b<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//decltype(c) is integer<=
32></span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> d </span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> add_carry</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">a</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify">//dec=
ltyp(d)is integer<33></span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br><br></span><font color=3D"#666600"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">(</span></font><span style=3D"color: #000;" =
class=3D"styled-by-prettify">d</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">carry_flag_set</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">())</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">}</span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">//Tests the highest bit in t=
he value</span></div></code></div><br>You could also write a more specific =
carrying math integer type that's not called std::integer. This one could h=
ave a carry flag bit semantics on its operations and a user configurable te=
mplate policy for how to handle what you consider errors (e.g. throw, asser=
t, log, etc..).</div><div><br></div><div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><font color=3D"#660066"><span style=3D"color: #800;" class=3D"s=
tyled-by-prettify">//In my library header</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">template</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">size_t N</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">using=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> my_carry_=
int </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">carry_int</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">N</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">carry_int_assert</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">>;</span></font></div></code></div><br><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" 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_348_963266678.1433467013111--
------=_Part_347_916968410.1433467013111--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 5 Jun 2015 12:08:38 -0700
Raw View
--001a113d5d12fe4a6f0517ca0416
Content-Type: text/plain; charset=UTF-8
On Thu, Jun 4, 2015 at 6:16 PM, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:
>
>
> On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard Smith wrote:
>>
>> On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein <mklei...@gmail.com> wrote:
>>
>>> Hi Richard.
>>> The library based standard would be something equivalent to what is
>>> already available in each respective environment (and implemented
>>> differently.) I provided a link to gcc:
>>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>>
>>> But the whole point is to have a clearer and shorter and more powerful
>>> standardized code , it is possible to do only with core syntax
>>> extension.
>>>
>>
>> That's not true. The GCC builtins are one possible library interface, but
>> there are other interfaces that would give a clearer and shorter syntax
>> while still being a library solution. For instance, something like this is
>> easy to implement:
>>
>> // Compute some function with 32-bit wraparound.
>> int32_t f(wrapping_int32 a, wrapping_int32 b) {
>> return a * a + b;
>> }
>>
>> ... and likewise you can implement a library where this works:
>>
>> integer<32> a, b;
>> // ...
>> integer<33> s = a + b;
>>
>
> If you want to use a generic type like integer<N>, it might be better to
> use a function call for this operation to show that its doing something
> different than the expected behavior for adding 2 numbers. It will also
> allow type deduction to be used
>
> template <size_t N, size_t M>
> integer<N > M ? N + 1 : M + 1> add_carry(integer<N> l, integer<M> r);
>
> integer<32> a;
> integer<32> b;
>
> auto c = a + b; //decltype(c) is integer<32>
> auto d = add_carry(a, b); //decltyp(d)is integer<33>
>
> if(d.carry_flag_set()) { }//Tests the highest bit in the value
>
My intention was that the operator+ had the semantics of your add_carry
function: that is, it returns a type that is guaranteed to be large enough
to represent the result of the operation (and likewise for the other
operators). Adding another type that can silently overflow doesn't seem
like the best option to me.
You could also write a more specific carrying math integer type that's not
> called std::integer. This one could have a carry flag bit semantics on its
> operations and a user configurable template policy for how to handle what
> you consider errors (e.g. throw, assert, log, etc..).
>
> //In my library header
> template <size_t N>
> using my_carry_int = std::carry_int<N, std::carry_int_assert>;
>
I think "carrying" is too low a level of abstraction for this. Instead, I
think it's a lot better to have a type that simply models "an integer",
with explicit truncation / wrapping at points the user chooses.
--
---
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/.
--001a113d5d12fe4a6f0517ca0416
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 T=
hu, Jun 4, 2015 at 6:16 PM, Matthew Fioravante <span dir=3D"ltr"><<a hre=
f=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.co=
m</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<br><br>On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard Smith wrote:=
<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><div class=3D"gmail_quote">On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein=
<span dir=3D"ltr"><<a rel=3D"nofollow">mklei...@gmail.com</a>></span=
> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-s=
tyle:solid;padding-left:1ex">Hi Richard.<br>
The library based standard would be something equivalent to what is<br>
already available in each respective environment (and implemented<br>
differently.) I provided a link to gcc:<br>
<a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.htm=
l" rel=3D"nofollow" target=3D"_blank">https://gcc.gnu.org/onlinedocs/gcc/In=
teger-Overflow-Builtins.html</a><br>
<br>
But the whole point is to have a clearer and shorter and more powerful<br>
standardized code , it is possible to do only with core syntax<br>
extension.<br></blockquote><div><br></div><div>That's not true. The GCC=
builtins are one possible library interface, but there are other interface=
s that would give a clearer and shorter syntax while still being a library =
solution. For instance, something like this is easy to implement:</div><div=
><br></div><div>// Compute some function with 32-bit wraparound.</div><div>=
int32_t f(wrapping_int32 a, wrapping_int32 b) {</div><div>=C2=A0 return a *=
a + b;</div><div>}</div><div><br></div><div>... and likewise you can imple=
ment a library where this works:</div><div><br></div><div>integer<32>=
a, b;</div><div>// ...<br></div><div>integer<33> s =3D a + b;</div><=
/div></div></div></blockquote><div><br></div></span><div>If you want to use=
a generic type like integer<N>, it might be better to use a function=
call for this operation to show that its doing something different than th=
e expected behavior for adding 2 numbers. It will also allow type deduction=
to be used</div><div><br></div><div><div style=3D"border:1px solid rgb(187=
,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><di=
v><span style=3D"color:#008">template</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660"><</span><span style=3D"color:#000">size_t=
N</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> siz=
e_t M</span><span style=3D"color:#660">></span><span style=3D"color:#000=
"><br>integer</span><span style=3D"color:#660"><</span><span style=3D"co=
lor:#000">N </span><span style=3D"color:#660">></span><span style=3D"col=
or:#000"> M </span><span style=3D"color:#660">?</span><span style=3D"color:=
#000"> N </span><span style=3D"color:#660">+</span><span style=3D"color:#00=
0"> </span><span style=3D"color:#066">1</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">:</span><span style=3D"color:#000"> M </sp=
an><span style=3D"color:#660">+</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#066">1</span><span style=3D"color:#660">></span><spa=
n style=3D"color:#000"> add_carry</span><span style=3D"color:#660">(</span>=
<span style=3D"color:#000">integer</span><span style=3D"color:#660"><</s=
pan><span style=3D"color:#000">N</span><span style=3D"color:#660">></spa=
n><span style=3D"color:#000"> l</span><span style=3D"color:#660">,</span><s=
pan style=3D"color:#000"> integer</span><span style=3D"color:#660"><</sp=
an><span style=3D"color:#000">M</span><span style=3D"color:#660">></span=
><span style=3D"color:#000"> r</span><span style=3D"color:#660">);</span><s=
pan style=3D"color:#000"><br><br>integer</span><span style=3D"color:#660">&=
lt;</span><span style=3D"color:#066">32</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> a</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"><br>integer</span><span style=3D"color:#660=
"><</span><span style=3D"color:#066">32</span><span style=3D"color:#660"=
>></span><span style=3D"color:#000"> b</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">auto</span><span style=3D"color:#000"> c </span><span style=3D"color:#660=
">=3D</span><span style=3D"color:#000"> a </span><span style=3D"color:#660"=
>+</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;</=
span><span style=3D"color:#000"> </span><span style=3D"color:#800">//declty=
pe(c) is integer<32></span><span style=3D"color:#000"><br></span><spa=
n style=3D"color:#008">auto</span><span style=3D"color:#000"> d </span><spa=
n style=3D"color:#660">=3D</span><span style=3D"color:#000"> add_carry</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">a</span><sp=
an style=3D"color:#660">,</span><span style=3D"color:#000"> b</span><span s=
tyle=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">//decltyp(d)is integer<33></span><span style=3D"color=
:#000"><br><br></span><font color=3D"#666600"><span style=3D"color:#008">if=
</span><span style=3D"color:#660">(</span></font><span style=3D"color:#000"=
>d</span><span style=3D"color:#660">.</span><span style=3D"color:#000">carr=
y_flag_set</span><span style=3D"color:#660">())</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}</span><span style=3D"color:#800">//Te=
sts the highest bit in the value</span></div></code></div></div></div></blo=
ckquote><div><br></div><div>My intention was that the operator+ had the sem=
antics of your add_carry function: that is, it returns a type that is guara=
nteed to be large enough to represent the result of the operation (and like=
wise for the other operators). Adding another type that can silently overfl=
ow doesn't seem like the best option to me.</div><div><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc =
solid;padding-left:1ex"><div dir=3D"ltr"><div>You could also write a more s=
pecific carrying math integer type that's not called std::integer. This=
one could have a carry flag bit semantics on its operations and a user con=
figurable template policy for how to handle what you consider errors (e.g. =
throw, assert, log, etc..).</div><div><br></div><div><div style=3D"border:1=
px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250=
,250)"><code><div><font color=3D"#660066"><span style=3D"color:#800">//In m=
y library header</span><span style=3D"color:#000"><br></span><span style=3D=
"color:#008">template</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660"><</span><span style=3D"color:#000">size_t N</span><span =
style=3D"color:#660">></span><span style=3D"color:#000"><br></span><span=
style=3D"color:#008">using</span><span style=3D"color:#000"> my_carry_int =
</span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">carry=
_int</span><span style=3D"color:#660"><</span><span style=3D"color:#000"=
>N</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> std=
</span><span style=3D"color:#660">::</span><span style=3D"color:#000">carry=
_int_assert</span><span style=3D"color:#660">>;</span></font></div></cod=
e></div></div></div></blockquote><div><br></div><div>I think "carrying=
" is too low a level of abstraction for this. Instead, I think it'=
s a lot better to have a type that simply models "an integer", wi=
th explicit truncation / wrapping at points the user chooses.</div></div></=
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" 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 />
--001a113d5d12fe4a6f0517ca0416--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 5 Jun 2015 12:22:28 -0700 (PDT)
Raw View
------=_Part_502_1546893651.1433532148211
Content-Type: multipart/alternative;
boundary="----=_Part_503_1204561775.1433532148211"
------=_Part_503_1204561775.1433532148211
Content-Type: text/plain; charset=UTF-8
On Friday, June 5, 2015 at 3:08:39 PM UTC-4, Richard Smith wrote:
>
> On Thu, Jun 4, 2015 at 6:16 PM, Matthew Fioravante <fmatth...@gmail.com
> <javascript:>> wrote:
>
>> On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard Smith wrote:
>>>
>>> On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein <mklei...@gmail.com> wrote:
>>>
>>>> Hi Richard.
>>>> The library based standard would be something equivalent to what is
>>>> already available in each respective environment (and implemented
>>>> differently.) I provided a link to gcc:
>>>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>>>
>>>> But the whole point is to have a clearer and shorter and more powerful
>>>> standardized code , it is possible to do only with core syntax
>>>> extension.
>>>>
>>>
>>> That's not true. The GCC builtins are one possible library interface,
>>> but there are other interfaces that would give a clearer and shorter syntax
>>> while still being a library solution. For instance, something like this is
>>> easy to implement:
>>>
>>> // Compute some function with 32-bit wraparound.
>>> int32_t f(wrapping_int32 a, wrapping_int32 b) {
>>> return a * a + b;
>>> }
>>>
>>> ... and likewise you can implement a library where this works:
>>>
>>> integer<32> a, b;
>>> // ...
>>> integer<33> s = a + b;
>>>
>>
>> If you want to use a generic type like integer<N>, it might be better to
>> use a function call for this operation to show that its doing something
>> different than the expected behavior for adding 2 numbers. It will also
>> allow type deduction to be used
>>
>> template <size_t N, size_t M>
>> integer<N > M ? N + 1 : M + 1> add_carry(integer<N> l, integer<M> r);
>>
>> integer<32> a;
>> integer<32> b;
>>
>> auto c = a + b; //decltype(c) is integer<32>
>> auto d = add_carry(a, b); //decltyp(d)is integer<33>
>>
>> if(d.carry_flag_set()) { }//Tests the highest bit in the value
>>
>
> My intention was that the operator+ had the semantics of your add_carry
> function: that is, it returns a type that is guaranteed to be large enough
> to represent the result of the operation (and likewise for the other
> operators). Adding another type that can silently overflow doesn't seem
> like the best option to me.
>
> You could also write a more specific carrying math integer type that's not
>> called std::integer. This one could have a carry flag bit semantics on its
>> operations and a user configurable template policy for how to handle what
>> you consider errors (e.g. throw, assert, log, etc..).
>>
>> //In my library header
>> template <size_t N>
>> using my_carry_int = std::carry_int<N, std::carry_int_assert>;
>>
>
> I think "carrying" is too low a level of abstraction for this. Instead, I
> think it's a lot better to have a type that simply models "an integer",
> with explicit truncation / wrapping at points the user chooses.
>
Not to mention that having an arbitrarily sized integer is useful for more
than just truncation and wrapping.
--
---
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_503_1204561775.1433532148211
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Friday, June 5, 2015 at 3:08:39 PM UTC-4, Richard Smith=
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><=
div class=3D"gmail_quote">On Thu, Jun 4, 2015 at 6:16 PM, Matthew Fioravant=
e <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" gdf-obfus=
cated-mailto=3D"slEFIayefA0J" rel=3D"nofollow" onmousedown=3D"this.href=3D'=
javascript:';return true;" onclick=3D"this.href=3D'javascript:';return true=
;">fmatth...@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr">On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard=
Smith wrote:<span><blockquote class=3D"gmail_quote" style=3D"margin:0;marg=
in-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"=
><div><div class=3D"gmail_quote">On Wed, Jun 3, 2015 at 7:12 PM, Marian Kle=
in <span dir=3D"ltr"><<a rel=3D"nofollow">mklei...@gmail.com</a>></sp=
an> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left=
-style:solid;padding-left:1ex">Hi Richard.<br>
The library based standard would be something equivalent to what is<br>
already available in each respective environment (and implemented<br>
differently.) I provided a link to gcc:<br>
<a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.htm=
l" rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://w=
ww.google.com/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FIntege=
r-Overflow-Builtins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwxXm6u=
VuUz-BV2oZaEQ';return true;" onclick=3D"this.href=3D'https://www.google.com=
/url?q\75https%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FInteger-Overflow-Bu=
iltins.html\46sa\75D\46sntz\0751\46usg\75AFQjCNETPHTQImpwxXm6uVuUz-BV2oZaEQ=
';return true;">https://gcc.gnu.org/<wbr>onlinedocs/gcc/Integer-<wbr>Overfl=
ow-Builtins.html</a><br>
<br>
But the whole point is to have a clearer and shorter and more powerful<br>
standardized code , it is possible to do only with core syntax<br>
extension.<br></blockquote><div><br></div><div>That's not true. The GCC bui=
ltins are one possible library interface, but there are other interfaces th=
at would give a clearer and shorter syntax while still being a library solu=
tion. For instance, something like this is easy to implement:</div><div><br=
></div><div>// Compute some function with 32-bit wraparound.</div><div>int3=
2_t f(wrapping_int32 a, wrapping_int32 b) {</div><div> return a * a +=
b;</div><div>}</div><div><br></div><div>... and likewise you can implement=
a library where this works:</div><div><br></div><div>integer<32> a, =
b;</div><div>// ...<br></div><div>integer<33> s =3D a + b;</div></div=
></div></div></blockquote><div><br></div></span><div>If you want to use a g=
eneric type like integer<N>, it might be better to use a function cal=
l for this operation to show that its doing something different than the ex=
pected behavior for adding 2 numbers. It will also allow type deduction to =
be used</div><div><br></div><div><div style=3D"border:1px solid rgb(187,187=
,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div><s=
pan style=3D"color:#008">template</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#660"><</span><span style=3D"color:#000">size_t N</=
span><span style=3D"color:#660">,</span><span style=3D"color:#000"> size_t =
M</span><span style=3D"color:#660">></span><span style=3D"color:#000"><b=
r>integer</span><span style=3D"color:#660"><</span><span style=3D"color:=
#000">N </span><span style=3D"color:#660">></span><span style=3D"color:#=
000"> M </span><span style=3D"color:#660">?</span><span style=3D"color:#000=
"> N </span><span style=3D"color:#660">+</span><span style=3D"color:#000"> =
</span><span style=3D"color:#066">1</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#660">:</span><span style=3D"color:#000"> M </span><=
span style=3D"color:#660">+</span><span style=3D"color:#000"> </span><span =
style=3D"color:#066">1</span><span style=3D"color:#660">></span><span st=
yle=3D"color:#000"> add_carry</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#000">integer</span><span style=3D"color:#660"><</span>=
<span style=3D"color:#000">N</span><span style=3D"color:#660">></span><s=
pan style=3D"color:#000"> l</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> integer</span><span style=3D"color:#660"><</span><=
span style=3D"color:#000">M</span><span style=3D"color:#660">></span><sp=
an style=3D"color:#000"> r</span><span style=3D"color:#660">);</span><span =
style=3D"color:#000"><br><br>integer</span><span style=3D"color:#660"><<=
/span><span style=3D"color:#066">32</span><span style=3D"color:#660">></=
span><span style=3D"color:#000"> a</span><span style=3D"color:#660">;</span=
><span style=3D"color:#000"><br>integer</span><span style=3D"color:#660">&l=
t;</span><span style=3D"color:#066">32</span><span style=3D"color:#660">>=
;</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;</s=
pan><span style=3D"color:#000"><br><br></span><span style=3D"color:#008">au=
to</span><span style=3D"color:#000"> c </span><span style=3D"color:#660">=
=3D</span><span style=3D"color:#000"> a </span><span style=3D"color:#660">+=
</span><span style=3D"color:#000"> b</span><span style=3D"color:#660">;</sp=
an><span style=3D"color:#000"> </span><span style=3D"color:#800">//decltype=
(c) is integer<32></span><span style=3D"color:#000"><br></span><span =
style=3D"color:#008">auto</span><span style=3D"color:#000"> d </span><span =
style=3D"color:#660">=3D</span><span style=3D"color:#000"> add_carry</span>=
<span style=3D"color:#660">(</span><span style=3D"color:#000">a</span><span=
style=3D"color:#660">,</span><span style=3D"color:#000"> b</span><span sty=
le=3D"color:#660">);</span><span style=3D"color:#000"> </span><span style=
=3D"color:#800">//decltyp(d)is integer<33></span><span style=3D"color=
:#000"><br><br></span><font color=3D"#666600"><span style=3D"color:#008">if=
</span><span style=3D"color:#660">(</span></font><span style=3D"color:#000"=
>d</span><span style=3D"color:#660">.</span><span style=3D"color:#000">carr=
y_flag_set</span><span style=3D"color:#660">())</span><span style=3D"color:=
#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:#000"=
> </span><span style=3D"color:#660">}</span><span style=3D"color:#800">//Te=
sts the highest bit in the value</span></div></code></div></div></div></blo=
ckquote><div><br></div><div>My intention was that the operator+ had the sem=
antics of your add_carry function: that is, it returns a type that is guara=
nteed to be large enough to represent the result of the operation (and like=
wise for the other operators). Adding another type that can silently overfl=
ow doesn't seem like the best option to me.</div><div><br></div><blockquote=
class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr"><div>You could also write a more speci=
fic carrying math integer type that's not called std::integer. This one cou=
ld have a carry flag bit semantics on its operations and a user configurabl=
e template policy for how to handle what you consider errors (e.g. throw, a=
ssert, log, etc..).</div><div><br></div><div><div style=3D"border:1px solid=
rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,250,250)"><=
code><div><font color=3D"#660066"><span style=3D"color:#800">//In my librar=
y header</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
008">template</span><span style=3D"color:#000"> </span><span style=3D"color=
:#660"><</span><span style=3D"color:#000">size_t N</span><span style=3D"=
color:#660">></span><span style=3D"color:#000"><br></span><span style=3D=
"color:#008">using</span><span style=3D"color:#000"> my_carry_int </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">carry_int</spa=
n><span style=3D"color:#660"><</span><span style=3D"color:#000">N</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> std</span><s=
pan style=3D"color:#660">::</span><span style=3D"color:#000">carry_int_asse=
rt</span><span style=3D"color:#660">>;</span></font></div></code></div><=
/div></div></blockquote><div><br></div><div>I think "carrying" is too low a=
level of abstraction for this. Instead, I think it's a lot better to have =
a type that simply models "an integer", with explicit truncation / wrapping=
at points the user chooses.</div></div></div></div></blockquote><div><br>N=
ot to mention that having an arbitrarily sized integer is useful for more t=
han just truncation and wrapping. <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" 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_503_1204561775.1433532148211--
------=_Part_502_1546893651.1433532148211--
.
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Fri, 5 Jun 2015 20:58:45 +0100
Raw View
Ok,ok , do NOT crucify me, I don't mind opposition. You convinced me
the library is the sufficient and better idea.
My requirements on library wrapper around native int types is:
1) Zero space overhead (for carry/overflow bit) to preserve binary
compatibility.(you can put into array)
2) Zero execution overhead for the default behaviour, when user does
not care about overflow.
I have an C++11 example:
#include <inttypes.h>
#include <iostream>
#include <vector>
struct overflow_handler_empty{ };
template <class uintT, bool overflow_enabled=false,
class
overflow_handler=overflow_handler_empty,
overflow_handler& oh=overflow_handler() >
struct safe_uint
{
uintT val=0;//C++11
safe_uint(uintT val1):val(val1){}
inline safe_uint& operator +=(uintT other)
{
if (overflow_enabled)//compile time code optimization
{
uintT oval=val;
val += other;
if (val<oval)
oh();
} else
val+=other;
return *this;
}
};
struct my_overflow_handler
{
uint64_t carry=0;//C++11
void operator()() {
++carry;
}
};
struct my_overflow_handler moh;
int main()
{
//struct my_overflow_handler moh;// why this cannot be on the stack
std::vector<uint64_t> vect(1000,0);
for (size_t i=0;i<vect.size();i++)
{
vect[i]=(1ULL<<63)|(1ULL<<62)|i;
}
safe_uint<uint64_t,true,my_overflow_handler,moh> safe_total=~0;
safe_total+=3;
std::cout << "carry:" << moh.carry << " safe_total=" <<
safe_total.val << std::endl;
safe_total.val=0;
moh.carry=0;
for (size_t i=0;i<vect.size();i++)
{
safe_total+=vect[i];
}
std::cout << "carry:" << moh.carry << " safe_total=" <<
safe_total.val << std::endl;
return 1;
}
This program correctly calculates total of values in the vector.
carry:1 safe_total=2
carry:750 safe_total=499500
So the total of the values in the vector is: 750*2^64 + 499500
Just small technical question: Why I cannot put line
struct my_overflow_handler moh;
on the stack?
It would be very desirable.
How would you address those limitation at the same time?
1) not to have handler object inside safe_uint due to space overhead constraint
2) to have a state in custom overflow handler to accumulate carry
3) to be able to use the handler on the stack locally to update local variables?
I tried to use lambda functions , but they are essentially function
objects that cannot be passed as a template non-type parameter.
I especially like the lambda functions capture mechanism of local
objects. That would be useful to manipulate local carry variables.
I am looking forward to suggestions.
best regards
Marian
On 5 June 2015 at 02:16, Matthew Fioravante <fmatthew5876@gmail.com> wrote:
>
>
> On Thursday, June 4, 2015 at 4:10:05 PM UTC-4, Richard Smith wrote:
>>
>> On Wed, Jun 3, 2015 at 7:12 PM, Marian Klein <mklei...@gmail.com> wrote:
>>>
>>> Hi Richard.
>>> The library based standard would be something equivalent to what is
>>> already available in each respective environment (and implemented
>>> differently.) I provided a link to gcc:
>>> https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
>>>
>>> But the whole point is to have a clearer and shorter and more powerful
>>> standardized code , it is possible to do only with core syntax
>>> extension.
>>
>>
>> That's not true. The GCC builtins are one possible library interface, but
>> there are other interfaces that would give a clearer and shorter syntax
>> while still being a library solution. For instance, something like this is
>> easy to implement:
>>
>> // Compute some function with 32-bit wraparound.
>> int32_t f(wrapping_int32 a, wrapping_int32 b) {
>> return a * a + b;
>> }
>>
>> ... and likewise you can implement a library where this works:
>>
>> integer<32> a, b;
>> // ...
>> integer<33> s = a + b;
>
>
> If you want to use a generic type like integer<N>, it might be better to use
> a function call for this operation to show that its doing something
> different than the expected behavior for adding 2 numbers. It will also
> allow type deduction to be used
>
> template <size_t N, size_t M>
> integer<N > M ? N + 1 : M + 1> add_carry(integer<N> l, integer<M> r);
>
> integer<32> a;
> integer<32> b;
>
> auto c = a + b; //decltype(c) is integer<32>
> auto d = add_carry(a, b); //decltyp(d)is integer<33>
>
> if(d.carry_flag_set()) { }//Tests the highest bit in the value
>
> You could also write a more specific carrying math integer type that's not
> called std::integer. This one could have a carry flag bit semantics on its
> operations and a user configurable template policy for how to handle what
> you consider errors (e.g. throw, assert, log, etc..).
>
> //In my library header
> template <size_t N>
> using my_carry_int = std::carry_int<N, std::carry_int_assert>;
>
>
> --
>
> ---
> 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/.
--
---
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: Nicol Bolas <jmckesson@gmail.com>
Date: Fri, 5 Jun 2015 13:42:11 -0700 (PDT)
Raw View
------=_Part_1491_1284981816.1433536931578
Content-Type: multipart/alternative;
boundary="----=_Part_1492_200658515.1433536931578"
------=_Part_1492_200658515.1433536931578
Content-Type: text/plain; charset=UTF-8
On Friday, June 5, 2015 at 3:58:47 PM UTC-4, Marian Klein wrote:
>
> Just small technical question: Why I cannot put line
> struct my_overflow_handler moh;
> on the stack?
>
You can put it on the stack just fine. What you *can't* do is use it as a
template parameter from the stack.
Non-type template arguments have to be stored in static memory. And the
stack isn't static memory.
> How would you address those limitation at the same time?
> 1) not to have handler object inside safe_uint due to space overhead
> constraint
> 2) to have a state in custom overflow handler to accumulate carry
> 3) to be able to use the handler on the stack locally to update local
> variables?
>
You wrote the requirement of zero-size overhead. That means that any
carryover must be externally stored. Overflow/carry storage has to go
*somewhere*. And since it can't go in a particular instance, it must go
into globally accessible memory.
The same goes for using the local stack for storing it. Using stack space
would require that your instance store a pointer/reference to the object.
Which violates your zero-size overhead principle. And therefore, the only
way to do that is through a reference to global memory.
You have to accept either local overhead or global overhead. You
prioritized a minimum of local overhead, so you get global overhead.
To be honest, I don't really see the point of the "no local overhead"
approach. Not only does it mean that different instances that use different
storage schemes are incompatible, it also means that you can't do two
completely separate computations, one after the other, without carry
information transferring from one computation to another. Something as
simple as creating two objects and operating independently of each is just
not possible.
To do that, each instance would have to use its own global state, or you
have to reset the global state between them. If they use different global
state, it makes interop difficult or impossible. And resetting between them
is way too error prone.
And that's ignoring threading issues.
It would be better to ditch the zero overhead principle and just store
extra data for the carries locally. Your way of using an external object is
just way too dangerous.
--
---
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_1492_200658515.1433536931578
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, June 5, 2015 at 3:58:47 PM UTC-4, Maria=
n Klein wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Just small techn=
ical question: Why I cannot put line
<br> struct my_overflow_handler moh;
<br>on the stack?<br></blockquote><div><br>You can put it on the stack just=
fine. What you <i>can't</i> do is use it as a template parameter from the =
stack.<br><br>Non-type template arguments have to be stored in static memor=
y. And the stack isn't static memory.<br> </div><blockquote class=3D"g=
mail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc sol=
id;padding-left: 1ex;">How would you address those limitation at the same t=
ime?
<br>1) not to have handler object inside safe_uint due to space overhead co=
nstraint
<br>2) to have a state in custom overflow handler to accumulate carry
<br>3) to be able to use the handler on the stack locally to update local v=
ariables?<br></blockquote><div><br>You wrote the requirement of zero-size o=
verhead. That means that any carryover must be externally stored. Overflow/=
carry storage has to go <i>somewhere</i>. And since it can't go in a partic=
ular instance, it must go into globally accessible memory.<br><br>The same =
goes for using the local stack for storing it. Using stack space would requ=
ire that your instance store a pointer/reference to the object. Which viola=
tes your zero-size overhead principle. And therefore, the only way to do th=
at is through a reference to global memory.<br><br>You have to accept eithe=
r local overhead or global overhead. You prioritized a minimum of local ove=
rhead, so you get global overhead.<br><br>To be honest, I don't really see =
the point of the "no local overhead" approach. Not only does it mean that d=
ifferent instances that use different storage schemes are incompatible, it =
also means that you can't do two completely separate computations, one afte=
r the other, without carry information transferring from one computation to=
another. Something as simple as creating two objects and operating indepen=
dently of each is just not possible.<br><br>To do that, each instance would=
have to use its own global state, or you have to reset the global state be=
tween them. If they use different global state, it makes interop difficult =
or impossible. And resetting between them is way too error prone.<br><br>An=
d that's ignoring threading issues.<br><br>It would be better to ditch the =
zero overhead principle and just store extra data for the carries locally. =
Your way of using an external object is just way too dangerous.<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" 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_1492_200658515.1433536931578--
------=_Part_1491_1284981816.1433536931578--
.
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Sat, 6 Jun 2015 03:31:19 +0100
Raw View
Hi guys.
I sumarize:
1) Assembler provides overflow/carry information for free. C/C++
designer decided not to expose that assembler information of the last
operation into language. To reintroduce it back requires some
penalties.
2) The guys rejected my idea of being able to detect overflow in
language itself (without additional space per object or runtime
overhead)
for unsigned int I wanted to do it in library.
3) I planned to have a thin low level library wrapper around native
int types that would detect efficiently only carry and overflow to
allow other developers build on top of that their more complex
classes. It is not possible to do without the significant penalties
and trade-offs.
4) Keeping 1 bit of information inside the object is not practical.
Even keeping one byte of information means, you cannot fit the whole
object nicely into array without the wasted space due to alignment.
5) The overflow handler specified as a non-typed template parameter
can be made only global (as oposed to desirable local) without storing
its pointer inside this thin wrapper object.
http://stackoverflow.com/questions/5687540/non-type-template-parameters.
Having a global overflow handler is still an option, this would
basically emulate the assembler by providing the global flag to only
the last arithmetic operation. Or alternatively the local user/local
handler could register temporarily (by putting on the
global stack std::stack his own local handler object with the global
handler, which would forward the execution into the local handler)
This global overflow flag could be made the thread local to
circumvent the multi-threading issues. Potentially we could have also
save/restore flags operations or using also std::stack to allow safe
local use.
It is better now just to go for higher level object that keep the
higher words along the least significant word essentially to create
arbitrarily long unsigned int.
Bellow are two stub classes composed_uint (implemented in terms of
C++11 std::array) and unbound_uint (implemented in terms of
std::vector).
Both are templated by wordT, which is meant to denote the natural
(the fastest) word (unsigned int) used by the CPU architecture.
composed_uint has few
disadvantages:1) you need to know the expected size upfront during the
compilation time,
2) The class still implements the modular
arithmetics (although with the much higher modulo than native word. ).
advantages:1) it has no space overhead and it fits nicely into arrays
with the same alignment as word
2) you can place it onto stack without any heap
allocation. (faster construction and fail safe, it cannot throw
exception)
3) you can detect carry/overflow with calling
variants of special non-operator functions
unbound_uint resizes itself runtime as needed (it is its main advantage) ,
it never experiences the overflow/wrap around in
modular arithmetics
(it will use as much memory as it can allocate)
or throw exception.
Questions: 1) Should be the unbound_uint be implemented in terms of
std::list<uintT>
or std::list<std::vector<uintT> > or
equivalents instead of std::vector to minimize reallocations when
resizing?
2) Should we have the template parameter wordT.
Does user care? or just number of bits he wants/needs (which would be
adjusted upwards to the multiple of
word)?
3) What should be the names?
dynamic_multiword_uint / static_multiword_uint , dynamic_long_uint
/ static_long_uint
(Maybe 'natural' = Unbound unsigned integers
are Natural numbers. )
4) Shall continue to elaborate/complete those two
stubs (plus signed int variants) towards potential prototype proposal
for C++17?
I don't want to waste my time if it has no
chance to succeed. It would allow the C++ having the capabilities
like scripting language such as
python.
#include <inttypes.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
template <class wordT,int count=2>
struct composed_uint
{
std::array<wordT, count> arr;//endiannes: the higher index, the more
significant word
composed_uint(wordT val1=0) {
for (int i=1;i<count;i++) arr[i]=0;
arr[0]=val1;
}
inline composed_uint& operator =(const composed_uint& other)
{
arr=other.arr;
return *this;
}
inline composed_uint& operator +=(const composed_uint& other)
{
add(other);
return *this;
}
bool add(const composed_uint& other)
{
wordT carry=0;
for (size_t i=0;i<count;i++)
{
wordT origval=arr[i];
arr[i]+=other.arr[i];
arr[i]+=carry;
carry=(arr[i]<origval);
}
return carry;
}
void swap(composed_uint& other) { arr.swap(other.arr); }
void dump() {
std::cout << "words:";
for (int i=arr.size()-1;i>=0;i--)
std::cout << arr[i] << ",";
std::cout << std::endl;
}
};
//______________________________________________________________________________________
template <class wordT>
struct unbound_uint
{
std::vector<wordT> vect;//endiannes: the higher index, the more
significant word
unbound_uint(wordT val1=0){vect.push_back(val1);}
inline unbound_uint& operator =(const unbound_uint& other)
{
vect=other.vect;
return *this;
}
inline unbound_uint& operator +=(const unbound_uint& other)
{
if (other.vect.size()>vect.size())
vect.resize(other.vect.size());
if (add_at_fixed_width(other))
vect.push_back(1);
return *this;
}
bool add_at_fixed_width( const unbound_uint& other)
//returns carry flag
//it works correctly only for other.v.size()<= v.size()
{
size_t nwords=vect.size();
size_t onwords=other.vect.size();
//assert(onwords<=nwords);
wordT carry=0;
for (size_t i=0;i<nwords;i++)
{
wordT origval=vect[i];
if (i<onwords)
vect[i]+=other.vect[i];
vect[i]+=carry;
carry=(vect[i]<origval);
}
return carry;
}
void swap(unbound_uint& other) { vect.swap(vect.arr); }
void expand(int nwords)
{
if (nwords>vect.size())
vect.resize(nwords,0);
}
void shrink_to_fit()
{
int n=vect.size();
if (n<2)
return;
int i=n-1;
for(;(i>0)&&(vect[i]==0);i--);
vect.resize(i+1);
}
void reserve(int nwords)
{
vect.reserve(nwords);
}
void dump() {
std::cout << "words:";
for (int i=vect.size()-1;i>=0;i--)
std::cout << vect[i] << ",";
std::cout << std::endl;
}
};
//__________________________________________________________________________
int main()
{
//struct my_overflow_handler moh;// why this cannot by on the stack
std::vector<uint64_t> vect(1000,0);
for (size_t i=0;i<vect.size();i++)
{
vect[i]=(1ULL<<63)|(1ULL<<62)|i;
}
//safe_uint<uint64_t,true,my_overflow_handler,moh> safe_total=~0;
composed_uint<uint64_t> safe_total;
//unbound_uint<uint64_t> safe_total;
safe_total+=3;
safe_total.dump();
safe_total=0;
for (size_t i=0;i<vect.size();i++)
{
safe_total+=vect[i];
}
safe_total.dump();
return 1;
}
Marian
On 5 June 2015 at 21:42, Nicol Bolas <jmckesson@gmail.com> wrote:
>
>
> On Friday, June 5, 2015 at 3:58:47 PM UTC-4, Marian Klein wrote:
>>
>> Just small technical question: Why I cannot put line
>> struct my_overflow_handler moh;
>> on the stack?
>
>
> You can put it on the stack just fine. What you can't do is use it as a
> template parameter from the stack.
>
> Non-type template arguments have to be stored in static memory. And the
> stack isn't static memory.
>
>>
>> How would you address those limitation at the same time?
>> 1) not to have handler object inside safe_uint due to space overhead
>> constraint
>> 2) to have a state in custom overflow handler to accumulate carry
>> 3) to be able to use the handler on the stack locally to update local
>> variables?
>
>
> You wrote the requirement of zero-size overhead. That means that any
> carryover must be externally stored. Overflow/carry storage has to go
> somewhere. And since it can't go in a particular instance, it must go into
> globally accessible memory.
>
> The same goes for using the local stack for storing it. Using stack space
> would require that your instance store a pointer/reference to the object.
> Which violates your zero-size overhead principle. And therefore, the only
> way to do that is through a reference to global memory.
>
> You have to accept either local overhead or global overhead. You prioritized
> a minimum of local overhead, so you get global overhead.
>
> To be honest, I don't really see the point of the "no local overhead"
> approach. Not only does it mean that different instances that use different
> storage schemes are incompatible, it also means that you can't do two
> completely separate computations, one after the other, without carry
> information transferring from one computation to another. Something as
> simple as creating two objects and operating independently of each is just
> not possible.
>
> To do that, each instance would have to use its own global state, or you
> have to reset the global state between them. If they use different global
> state, it makes interop difficult or impossible. And resetting between them
> is way too error prone.
>
> And that's ignoring threading issues.
>
> It would be better to ditch the zero overhead principle and just store extra
> data for the carries locally. Your way of using an external object is just
> way too dangerous.
>
> --
>
> ---
> 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/.
--
---
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: Sat, 06 Jun 2015 13:40:27 +0200
Raw View
On Saturday 06 June 2015 03:31:19 Marian Klein wrote:
> Hi guys.
>
> I sumarize:
> 1) Assembler provides overflow/carry information for free. C/C++
> designer decided not to expose that assembler information of the last
> operation into language. To reintroduce it back requires some
> penalties.
"Some assembler", not "assembler". There's no requirement that all machines
support carry/borrow flags.
> 2) The guys rejected my idea of being able to detect overflow in
> language itself (without additional space per object or runtime
> overhead)
> for unsigned int I wanted to do it in library.
Your solution would expose a thread-specific variable that corresponds to the
flag, but only on output. You wouldn't be allowed to set it.
--
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: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Sun, 7 Jun 2015 18:00:53 -0700 (PDT)
Raw View
------=_Part_1749_289622146.1433725253414
Content-Type: multipart/alternative;
boundary="----=_Part_1750_1481463720.1433725253414"
------=_Part_1750_1481463720.1433725253414
Content-Type: text/plain; charset=UTF-8
On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol Bolas wrote:
>
> You have to accept either local overhead or global overhead. You
> prioritized a minimum of local overhead, so you get global overhead.
>
>
There is a third option, make a procedural interface and store the overflow
flag state in an extra local variable provided by the caller.
//Add l and r and return the result. If overflow occurs, set cf to true
template <typename Integral>
auto add_overflow(bool& cf, Integral l, Integral r);
bool overflow = false;
auto d = add_overflow(overflow, a, b);
Whether or not an overflow occurred is usually important only locally right
after an operation is performed. Do we really need to create an integer
type with the overhead of an extra bit of storage (likely resulting in
twice the total bits used due to alignment)? Having a thread-local (cannot
be global due to threading problems) variable also seems pretty heavy
weight.
--
---
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_1750_1481463720.1433725253414
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol=
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">=
<div>You have to accept either local overhead or global overhead. You prior=
itized a minimum of local overhead, so you get global overhead.<br><br></di=
v></div></blockquote><div><br></div><div>There is a third option, make a pr=
ocedural interface and store the overflow flag state in an extra local vari=
able provided by the caller.</div><div><br></div><div><div class=3D"prettyp=
rint" style=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word;=
background-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div cl=
ass=3D"subprettyprint"><span style=3D"color: #800;" class=3D"styled-by-pret=
tify">//Add l and r and return the result. If overflow occurs, set cf to tr=
ue</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">template</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">typename</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Integral</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">></span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> add_overflow</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">bool</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>&</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> cf<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><font color=
=3D"#000088"><span style=3D"color: #606;" class=3D"styled-by-prettify">Inte=
gral</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> l</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"=
color: #606;" class=3D"styled-by-prettify">Integral</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> r</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">);</span></font><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br></span><font color=3D"#000000"><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">bool</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> overflow </span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">false</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">auto</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> d=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> add_overflow</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">overflow</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> a</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> b</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">);</span></font><font color=3D"#000000"></font></div></cod=
e></div><br>Whether or not an overflow occurred is usually important only l=
ocally right after an operation is performed. Do we really need to create a=
n integer type with the overhead of an extra bit of storage (likely resulti=
ng in twice the total bits used due to alignment)? Having a thread-local (c=
annot be global due to threading problems) variable also seems pretty heavy=
weight.</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" 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_1750_1481463720.1433725253414--
------=_Part_1749_289622146.1433725253414--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Sun, 7 Jun 2015 18:49:03 -0700
Raw View
--001a1140a9d4b591f60517f7d810
Content-Type: text/plain; charset=UTF-8
On Sun, Jun 7, 2015 at 6:00 PM, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:
>
>
> On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol Bolas wrote:
>>
>> You have to accept either local overhead or global overhead. You
>> prioritized a minimum of local overhead, so you get global overhead.
>>
>>
> There is a third option, make a procedural interface and store the
> overflow flag state in an extra local variable provided by the caller.
>
> //Add l and r and return the result. If overflow occurs, set cf to true
> template <typename Integral>
> auto add_overflow(bool& cf, Integral l, Integral r);
>
> bool overflow = false;
> auto d = add_overflow(overflow, a, b);
>
> Whether or not an overflow occurred is usually important only locally
> right after an operation is performed. Do we really need to create an
> integer type with the overhead of an extra bit of storage (likely resulting
> in twice the total bits used due to alignment)?
>
Why would there be any extra storage? If you want to truncate prior to
storing the value somewhere, then do so.
And which would you prefer:
integer<64> f(integer<32> a, integer<32> b) {
auto x = a * a + b; // x is an integer<66>, but you don't really need to
care
return x.fits_in<64>() ? x.truncate_to<64>() : 0;
}
or
int64_t f(int32_t a, int32_t b) {
bool overflow = false;
int64_t r = add_overflow<int64_t>(overflow,
mul_overflow<int64_t>(overflow, a, a), b);
return overflow ? 0 : r;
}
?
Having a thread-local (cannot be global due to threading problems) variable
> also seems pretty heavy weight.
>
> --
>
> ---
> 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/.
>
--
---
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/.
--001a1140a9d4b591f60517f7d810
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 S=
un, Jun 7, 2015 at 6:00 PM, Matthew Fioravante <span dir=3D"ltr"><<a hre=
f=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.co=
m</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<span class=3D""><br><br>On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol=
Bolas wrote:<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>=
You have to accept either local overhead or global overhead. You prioritize=
d a minimum of local overhead, so you get global overhead.<br><br></div></d=
iv></blockquote><div><br></div></span><div>There is a third option, make a =
procedural interface and store the overflow flag state in an extra local va=
riable provided by the caller.</div><div><br></div><div><div style=3D"borde=
r:1px solid rgb(187,187,187);word-wrap:break-word;background-color:rgb(250,=
250,250)"><code><div><span style=3D"color:#800">//Add l and r and return th=
e result. If overflow occurs, set cf to true</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">template</span><span style=3D"colo=
r:#000"> </span><span style=3D"color:#660"><</span><span style=3D"color:=
#008">typename</span><span style=3D"color:#000"> </span><span style=3D"colo=
r:#606">Integral</span><span style=3D"color:#660">></span><span style=3D=
"color:#000"><br></span><span style=3D"color:#008">auto</span><span style=
=3D"color:#000"> add_overflow</span><span style=3D"color:#660">(</span><spa=
n style=3D"color:#008">bool</span><span style=3D"color:#660">&</span><s=
pan style=3D"color:#000"> cf</span><span style=3D"color:#660">,</span><span=
style=3D"color:#000"> </span><font color=3D"#000088"><span style=3D"color:=
#606">Integral</span><span style=3D"color:#000"> l</span><span style=3D"col=
or:#660">,</span><span style=3D"color:#000"> </span><span style=3D"color:#6=
06">Integral</span><span style=3D"color:#000"> r</span><span style=3D"color=
:#660">);</span></font><span style=3D"color:#000"><br></span><font color=3D=
"#000000"><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
bool</span><span style=3D"color:#000"> overflow </span><span style=3D"color=
:#660">=3D</span><span style=3D"color:#000"> </span><span style=3D"color:#0=
08">false</span><span style=3D"color:#660">;</span><span style=3D"color:#00=
0"><br></span><span style=3D"color:#008">auto</span><span style=3D"color:#0=
00"> d </span><span style=3D"color:#660">=3D</span><span style=3D"color:#00=
0"> add_overflow</span><span style=3D"color:#660">(</span><span style=3D"co=
lor:#000">overflow</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> a</span><span style=3D"color:#660">,</span><span style=3D"colo=
r:#000"> b</span><span style=3D"color:#660">);</span></font><font color=3D"=
#000000"></font></div></code></div><br>Whether or not an overflow occurred =
is usually important only locally right after an operation is performed. Do=
we really need to create an integer type with the overhead of an extra bit=
of storage (likely resulting in twice the total bits used due to alignment=
)?</div></div></blockquote><div><br></div><div>Why would there be any extra=
storage? If you want to truncate prior to storing the value somewhere, the=
n do so.</div><div><br></div><div>And which would you prefer:</div><div><br=
></div><div>integer<64> f(integer<32> a, integer<32> b) {=
</div><div>=C2=A0 auto x =3D a * a + b; // x is an integer<66>, but y=
ou don't really need to care</div><div>=C2=A0 return x.fits_in<64>=
;() ? x.truncate_to<64>() : 0;</div><div>}</div><div><br></div><div>o=
r</div><div><br></div><div>int64_t f(int32_t a, int32_t b) {</div><div>=C2=
=A0 bool overflow =3D false;</div><div>=C2=A0 int64_t r =3D add_overflow<=
;int64_t>(overflow, mul_overflow<int64_t>(overflow, a, a), b);</di=
v><div>=C2=A0 return overflow ? 0 : r;</div><div>}</div><div><br></div><div=
>?</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 =
0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div=
>Having a thread-local (cannot be global due to threading problems) variabl=
e also seems pretty heavy weight.</div></div><div class=3D"HOEnZb"><div cla=
ss=3D"h5">
<p></p>
-- <br>
<br>
--- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</div></div></blockquote></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" 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 />
--001a1140a9d4b591f60517f7d810--
.
Author: Matthew Fioravante <fmatthew5876@gmail.com>
Date: Sun, 7 Jun 2015 19:02:59 -0700 (PDT)
Raw View
------=_Part_606_444021636.1433728979361
Content-Type: multipart/alternative;
boundary="----=_Part_607_165962927.1433728979361"
------=_Part_607_165962927.1433728979361
Content-Type: text/plain; charset=UTF-8
On Sunday, June 7, 2015 at 9:49:06 PM UTC-4, Richard Smith wrote:
>
> On Sun, Jun 7, 2015 at 6:00 PM, Matthew Fioravante <fmatth...@gmail.com
> <javascript:>> wrote:
>
>>
>>
>> On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol Bolas wrote:
>>>
>>> You have to accept either local overhead or global overhead. You
>>> prioritized a minimum of local overhead, so you get global overhead.
>>>
>>>
>> There is a third option, make a procedural interface and store the
>> overflow flag state in an extra local variable provided by the caller.
>>
>> //Add l and r and return the result. If overflow occurs, set cf to true
>> template <typename Integral>
>> auto add_overflow(bool& cf, Integral l, Integral r);
>>
>> bool overflow = false;
>> auto d = add_overflow(overflow, a, b);
>>
>> Whether or not an overflow occurred is usually important only locally
>> right after an operation is performed. Do we really need to create an
>> integer type with the overhead of an extra bit of storage (likely resulting
>> in twice the total bits used due to alignment)?
>>
>
> Why would there be any extra storage? If you want to truncate prior to
> storing the value somewhere, then do so.
>
> And which would you prefer:
>
> integer<64> f(integer<32> a, integer<32> b) {
> auto x = a * a + b; // x is an integer<66>, but you don't really need to
> care
> return x.fits_in<64>() ? x.truncate_to<64>() : 0;
> }
>
Should it really be std::integer with this behavior? There is value in a
compile time sized integer outside of this use case and I believe most
people would expect std::integer<N> to behave like int by default.
There could be some other type just like std::integer, or maybe a template
policy for std::integer which has the growing size semantics you describe.
>
> or
>
> int64_t f(int32_t a, int32_t b) {
> bool overflow = false;
> int64_t r = add_overflow<int64_t>(overflow,
> mul_overflow<int64_t>(overflow, a, a), b);
> return overflow ? 0 : r;
> }
>
There are other use cases for the carry flag. For example maybe you want it
to be an error if an operation overflows. By providing a simple function to
perform this operation we can enable all possible use cases easily. These
functions can also be used to implement your std::integer.
--
---
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_607_165962927.1433728979361
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Sunday, June 7, 2015 at 9:49:06 PM UTC-4, Richa=
rd Smith 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><div class=3D"gmail_quote">On Sun, Jun 7, 2015 at 6:00 PM, Matthew F=
ioravante <span dir=3D"ltr"><<a href=3D"javascript:" target=3D"_blank" g=
df-obfuscated-mailto=3D"PgokvaFhYE4J" rel=3D"nofollow" onmousedown=3D"this.=
href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';ret=
urn true;">fmatth...@gmail.com</a>></span> wrote:<br><blockquote class=
=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><span><br><br>On Friday, June 5, 2015 at 4:4=
2:11 PM UTC-4, Nicol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D=
"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>You have to accept either local overhead or global over=
head. You prioritized a minimum of local overhead, so you get global overhe=
ad.<br><br></div></div></blockquote><div><br></div></span><div>There is a t=
hird option, make a procedural interface and store the overflow flag state =
in an extra local variable provided by the caller.</div><div><br></div><div=
><div style=3D"border:1px solid rgb(187,187,187);word-wrap:break-word;backg=
round-color:rgb(250,250,250)"><code><div><span style=3D"color:#800">//Add l=
and r and return the result. If overflow occurs, set cf to true</span><spa=
n style=3D"color:#000"><br></span><span style=3D"color:#008">template</span=
><span style=3D"color:#000"> </span><span style=3D"color:#660"><</span><=
span style=3D"color:#008">typename</span><span style=3D"color:#000"> </span=
><span style=3D"color:#606">Integral</span><span style=3D"color:#660">><=
/span><span style=3D"color:#000"><br></span><span style=3D"color:#008">auto=
</span><span style=3D"color:#000"> add_overflow</span><span style=3D"color:=
#660">(</span><span style=3D"color:#008">bool</span><span style=3D"color:#6=
60">&</span><span style=3D"color:#000"> cf</span><span style=3D"color:#=
660">,</span><span style=3D"color:#000"> </span><font color=3D"#000088"><sp=
an style=3D"color:#606">Integral</span><span style=3D"color:#000"> l</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> </span><span=
style=3D"color:#606">Integral</span><span style=3D"color:#000"> r</span><s=
pan style=3D"color:#660">);</span></font><span style=3D"color:#000"><br></s=
pan><font color=3D"#000000"><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">bool</span><span style=3D"color:#000"> overflow </span><s=
pan style=3D"color:#660">=3D</span><span style=3D"color:#000"> </span><span=
style=3D"color:#008">false</span><span style=3D"color:#660">;</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">auto</span><span=
style=3D"color:#000"> d </span><span style=3D"color:#660">=3D</span><span =
style=3D"color:#000"> add_overflow</span><span style=3D"color:#660">(</span=
><span style=3D"color:#000">overflow</span><span style=3D"color:#660">,</sp=
an><span style=3D"color:#000"> a</span><span style=3D"color:#660">,</span><=
span style=3D"color:#000"> b</span><span style=3D"color:#660">);</span></fo=
nt><font color=3D"#000000"></font></div></code></div><br>Whether or not an =
overflow occurred is usually important only locally right after an operatio=
n is performed. Do we really need to create an integer type with the overhe=
ad of an extra bit of storage (likely resulting in twice the total bits use=
d due to alignment)?</div></div></blockquote><div><br></div><div>Why would =
there be any extra storage? If you want to truncate prior to storing the va=
lue somewhere, then do so.</div><div><br></div><div>And which would you pre=
fer:</div><div><br></div><div>integer<64> f(integer<32> a, inte=
ger<32> b) {</div><div> auto x =3D a * a + b; // x is an intege=
r<66>, but you don't really need to care</div><div> return x.fi=
ts_in<64>() ? x.truncate_to<64>() : 0;</div><div>}</div></div><=
/div></div></blockquote><div><br></div><div>Should it really be std::intege=
r with this behavior? There is value in a compile time sized integer outsid=
e of this use case and I believe most people would expect std::integer<N=
> to behave like int by default.</div><div><br></div><div>There could be=
some other type just like std::integer, or maybe a template policy for std=
::integer which has the growing size semantics you describe.</div><div>&nbs=
p;</div><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>=
<div class=3D"gmail_quote"><div><br></div><div>or</div><div><br></div><div>=
int64_t f(int32_t a, int32_t b) {</div><div> bool overflow =3D false;=
</div><div> int64_t r =3D add_overflow<int64_t>(<wbr>overflow, =
mul_overflow<int64_t>(<wbr>overflow, a, a), b);</div><div> retu=
rn overflow ? 0 : r;</div><div>}</div></div></div></div></blockquote><div><=
br></div><div>There are other use cases for the carry flag. For example may=
be you want it to be an error if an operation overflows. By providing a sim=
ple function to perform this operation we can enable all possible use cases=
easily. These functions can also be used to implement your std::integer.</=
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" 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_607_165962927.1433728979361--
------=_Part_606_444021636.1433728979361--
.
Author: Edward Catmur <ed@catmur.co.uk>
Date: Tue, 9 Jun 2015 02:52:59 -0700 (PDT)
Raw View
------=_Part_229_306277250.1433843579031
Content-Type: multipart/alternative;
boundary="----=_Part_230_83438891.1433843579032"
------=_Part_230_83438891.1433843579032
Content-Type: text/plain; charset=UTF-8
On Monday, 8 June 2015 03:02:59 UTC+1, Matthew Fioravante wrote:
>
> There are other use cases for the carry flag. For example maybe you want
> it to be an error if an operation overflows. By providing a simple function
> to perform this operation we can enable all possible use cases easily.
> These functions can also be used to implement your std::integer.
>
I agree entirely. Given that it's preferred to standardize existing
practice, perhaps we should look at what extensions vendors already provide?
* Clang provides both multiprecision arithmetic primitives
(carry-in/carry-out):
http://clang.llvm.org/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins
and overflow-checked
arithmetic: http://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins
* gcc provides only overflow-checked
arithmetic: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html#Integer-Overflow-Builtins
with the same interface as clang and the same names.
* MSVC provides multiprecision intrinsics (depending on architecture)
addcarry, subborrow, and
emul: https://msdn.microsoft.com/en-us/library/hh977022.aspx
Some considerations:
* Include multiprecision arithmetic, overflow-checked arithmetic or both?
* Subtract: carry or
borrow? http://en.wikipedia.org/wiki/Carry_flag#Carry_flag_vs._Borrow_flag
* Should extended-precision multiplication be included (is it available on
enough architectures, and if not can it be emulated efficiently)?
* Naming (bikeshed warning): std::add_carry, std::sub_borrow, std::emul,
std::add_overflow, std::sub_overflow, std::mul_overflow?
* Multiple return values: out-parameters or struct return (as std::div())?
Also, I think that C compatibility would be valuable. That means that
out-parameters if used should be by pointer, not lvalue reference; and
templates are not viable. Overloads would not be out of the question (cf.
<tgmath>) but annotating the sign/width variants by prefix/suffix (s/u,
i/l/ll) would probably be preferred.
--
---
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_230_83438891.1433843579032
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, 8 June 2015 03:02:59 UTC+1, Matthew Fioravante =
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>T=
here are other use cases for the carry flag. For example maybe you want it =
to be an error if an operation overflows. By providing a simple function to=
perform this operation we can enable all possible use cases easily. These =
functions can also be used to implement your std::integer.</div></div></blo=
ckquote><div><br></div><div>I agree entirely. Given that it's preferred to =
standardize existing practice, perhaps we should look at what extensions ve=
ndors already provide?</div><div><br></div><div>* Clang provides both multi=
precision arithmetic primitives (carry-in/carry-out): http://clang.llvm.org=
/docs/LanguageExtensions.html#multiprecision-arithmetic-builtins and overfl=
ow-checked arithmetic: http://clang.llvm.org/docs/LanguageExtensions.h=
tml#checked-arithmetic-builtins</div><div>* gcc provides only overflow-chec=
ked arithmetic: https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Bu=
iltins.html#Integer-Overflow-Builtins with the same interface as clang and =
the same names.</div><div>* MSVC provides multiprecision intrinsics (depend=
ing on architecture) addcarry, subborrow, and emul: https://msdn.micro=
soft.com/en-us/library/hh977022.aspx</div><div><br></div><div>Some consider=
ations:</div><div><br></div><div>* Include multiprecision arithmetic, overf=
low-checked arithmetic or both?</div><div>* Subtract: carry or borrow? =
;http://en.wikipedia.org/wiki/Carry_flag#Carry_flag_vs._Borrow_flag</div><d=
iv>* Should extended-precision multiplication be included (is it available =
on enough architectures, and if not can it be emulated efficiently)?</div><=
div>* Naming (bikeshed warning): std::add_carry, std::sub_borrow, std::emul=
, std::add_overflow, std::sub_overflow, std::mul_overflow?</div><div>* Mult=
iple return values: out-parameters or struct return (as std::div())?</div><=
div><br></div><div>Also, I think that C compatibility would be valuable. Th=
at means that out-parameters if used should be by pointer, not lvalue refer=
ence; and templates are not viable. Overloads would not be out of the quest=
ion (cf. <tgmath>) but annotating the sign/width variants by prefix/s=
uffix (s/u, i/l/ll) would probably be preferred.</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" 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_230_83438891.1433843579032--
------=_Part_229_306277250.1433843579031--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Tue, 9 Jun 2015 11:28:47 -0700
Raw View
--089e01182cf2e1cfc6051819ed3d
Content-Type: text/plain; charset=UTF-8
On Sun, Jun 7, 2015 at 7:02 PM, Matthew Fioravante <fmatthew5876@gmail.com>
wrote:
>
>
> On Sunday, June 7, 2015 at 9:49:06 PM UTC-4, Richard Smith wrote:
>>
>> On Sun, Jun 7, 2015 at 6:00 PM, Matthew Fioravante <fmatth...@gmail.com>
>> wrote:
>>
>>>
>>>
>>> On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol Bolas wrote:
>>>>
>>>> You have to accept either local overhead or global overhead. You
>>>> prioritized a minimum of local overhead, so you get global overhead.
>>>>
>>>>
>>> There is a third option, make a procedural interface and store the
>>> overflow flag state in an extra local variable provided by the caller.
>>>
>>> //Add l and r and return the result. If overflow occurs, set cf to true
>>> template <typename Integral>
>>> auto add_overflow(bool& cf, Integral l, Integral r);
>>>
>>> bool overflow = false;
>>> auto d = add_overflow(overflow, a, b);
>>>
>>> Whether or not an overflow occurred is usually important only locally
>>> right after an operation is performed. Do we really need to create an
>>> integer type with the overhead of an extra bit of storage (likely resulting
>>> in twice the total bits used due to alignment)?
>>>
>>
>> Why would there be any extra storage? If you want to truncate prior to
>> storing the value somewhere, then do so.
>>
>> And which would you prefer:
>>
>> integer<64> f(integer<32> a, integer<32> b) {
>> auto x = a * a + b; // x is an integer<66>, but you don't really need
>> to care
>> return x.fits_in<64>() ? x.truncate_to<64>() : 0;
>> }
>>
>
> Should it really be std::integer with this behavior? There is value in a
> compile time sized integer outside of this use case and I believe most
> people would expect std::integer<N> to behave like int by default.
>
> There could be some other type just like std::integer, or maybe a template
> policy for std::integer which has the growing size semantics you describe.
>
>
>>
>> or
>>
>> int64_t f(int32_t a, int32_t b) {
>> bool overflow = false;
>> int64_t r = add_overflow<int64_t>(overflow,
>> mul_overflow<int64_t>(overflow, a, a), b);
>> return overflow ? 0 : r;
>> }
>>
>
> There are other use cases for the carry flag. For example maybe you want
> it to be an error if an operation overflows. By providing a simple function
> to perform this operation we can enable all possible use cases easily.
> These functions can also be used to implement your std::integer.
>
That would be very painful. Conversely, you could implement these
operations-with-a-carry-flag in terms of the integer<N> operations in a
very straightforward manner.
--
---
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/.
--089e01182cf2e1cfc6051819ed3d
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 S=
un, Jun 7, 2015 at 7:02 PM, Matthew Fioravante <span dir=3D"ltr"><<a hre=
f=3D"mailto:fmatthew5876@gmail.com" target=3D"_blank">fmatthew5876@gmail.co=
m</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi=
n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">=
<br><br>On Sunday, June 7, 2015 at 9:49:06 PM UTC-4, Richard Smith wrote:<s=
pan class=3D""><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"><di=
v><div class=3D"gmail_quote">On Sun, Jun 7, 2015 at 6:00 PM, Matthew Fiorav=
ante <span dir=3D"ltr"><<a rel=3D"nofollow">fmatth...@gmail.com</a>><=
/span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8=
ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span><br>=
<br>On Friday, June 5, 2015 at 4:42:11 PM UTC-4, Nicol Bolas wrote:<blockqu=
ote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1=
px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>You have to accept ei=
ther local overhead or global overhead. You prioritized a minimum of local =
overhead, so you get global overhead.<br><br></div></div></blockquote><div>=
<br></div></span><div>There is a third option, make a procedural interface =
and store the overflow flag state in an extra local variable provided by th=
e caller.</div><div><br></div><div><div style=3D"border:1px solid rgb(187,1=
87,187);word-wrap:break-word;background-color:rgb(250,250,250)"><code><div>=
<span style=3D"color:#800">//Add l and r and return the result. If overflow=
occurs, set cf to true</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">template</span><span style=3D"color:#000"> </span><span=
style=3D"color:#660"><</span><span style=3D"color:#008">typename</span>=
<span style=3D"color:#000"> </span><span style=3D"color:#606">Integral</spa=
n><span style=3D"color:#660">></span><span style=3D"color:#000"><br></sp=
an><span style=3D"color:#008">auto</span><span style=3D"color:#000"> add_ov=
erflow</span><span style=3D"color:#660">(</span><span style=3D"color:#008">=
bool</span><span style=3D"color:#660">&</span><span style=3D"color:#000=
"> cf</span><span style=3D"color:#660">,</span><span style=3D"color:#000"> =
</span><font color=3D"#000088"><span style=3D"color:#606">Integral</span><s=
pan style=3D"color:#000"> l</span><span style=3D"color:#660">,</span><span =
style=3D"color:#000"> </span><span style=3D"color:#606">Integral</span><spa=
n style=3D"color:#000"> r</span><span style=3D"color:#660">);</span></font>=
<span style=3D"color:#000"><br></span><font color=3D"#000000"><span style=
=3D"color:#000"><br></span><span style=3D"color:#008">bool</span><span styl=
e=3D"color:#000"> overflow </span><span style=3D"color:#660">=3D</span><spa=
n style=3D"color:#000"> </span><span style=3D"color:#008">false</span><span=
style=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span s=
tyle=3D"color:#008">auto</span><span style=3D"color:#000"> d </span><span s=
tyle=3D"color:#660">=3D</span><span style=3D"color:#000"> add_overflow</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#000">overflow</s=
pan><span style=3D"color:#660">,</span><span style=3D"color:#000"> a</span>=
<span style=3D"color:#660">,</span><span style=3D"color:#000"> b</span><spa=
n style=3D"color:#660">);</span></font><font color=3D"#000000"></font></div=
></code></div><br>Whether or not an overflow occurred is usually important =
only locally right after an operation is performed. Do we really need to cr=
eate an integer type with the overhead of an extra bit of storage (likely r=
esulting in twice the total bits used due to alignment)?</div></div></block=
quote><div><br></div><div>Why would there be any extra storage? If you want=
to truncate prior to storing the value somewhere, then do so.</div><div><b=
r></div><div>And which would you prefer:</div><div><br></div><div>integer&l=
t;64> f(integer<32> a, integer<32> b) {</div><div>=C2=A0 aut=
o x =3D a * a + b; // x is an integer<66>, but you don't really n=
eed to care</div><div>=C2=A0 return x.fits_in<64>() ? x.truncate_to&l=
t;64>() : 0;</div><div>}</div></div></div></div></blockquote><div><br></=
div></span><div>Should it really be std::integer with this behavior? There =
is value in a compile time sized integer outside of this use case and I bel=
ieve most people would expect std::integer<N> to behave like int by d=
efault.</div><div><br></div><div>There could be some other type just like s=
td::integer, or maybe a template policy for std::integer which has the grow=
ing size semantics you describe.</div><span class=3D""><div>=C2=A0</div><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-l=
eft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gm=
ail_quote"><div><br></div><div>or</div><div><br></div><div>int64_t f(int32_=
t a, int32_t b) {</div><div>=C2=A0 bool overflow =3D false;</div><div>=C2=
=A0 int64_t r =3D add_overflow<int64_t>(overflow, mul_overflow<int=
64_t>(overflow, a, a), b);</div><div>=C2=A0 return overflow ? 0 : r;</di=
v><div>}</div></div></div></div></blockquote><div><br></div></span><div>The=
re are other use cases for the carry flag. For example maybe you want it to=
be an error if an operation overflows. By providing a simple function to p=
erform this operation we can enable all possible use cases easily. These fu=
nctions can also be used to implement your std::integer.</div></div></block=
quote><div><br></div><div>That would be very painful. Conversely, you could=
implement these operations-with-a-carry-flag in terms of the integer<N&=
gt; operations in a very straightforward manner.</div></div></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" 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 />
--089e01182cf2e1cfc6051819ed3d--
.
Author: Olaf van der Spek <olafvdspek@gmail.com>
Date: Wed, 10 Jun 2015 04:53:14 -0700 (PDT)
Raw View
------=_Part_2122_811786398.1433937194273
Content-Type: multipart/alternative;
boundary="----=_Part_2123_510302313.1433937194273"
------=_Part_2123_510302313.1433937194273
Content-Type: text/plain; charset=UTF-8
Op maandag 8 juni 2015 03:49:06 UTC+2 schreef Richard Smith:
>
> Why would there be any extra storage? If you want to truncate prior to
> storing the value somewhere, then do so.
>
> And which would you prefer:
>
> integer<64> f(integer<32> a, integer<32> b) {
> auto x = a * a + b; // x is an integer<66>, but you don't really need to
> care
> return x.fits_in<64>() ? x.truncate_to<64>() : 0;
> }
>
> or
>
> int64_t f(int32_t a, int32_t b) {
> bool overflow = false;
> int64_t r = add_overflow<int64_t>(overflow,
> mul_overflow<int64_t>(overflow, a, a), b);
> return overflow ? 0 : r;
> }
>
The latter is likely to be faster then the former.
I'd go for basic GCC-style interface: bool add_overflow(res, a, b);
int64_t f(int32_t a, int32_t b) {
int64_t res;
return mul_overflow(res, a, a) || add_overflow(res, res, a) ? 0 : res;
}
One can always write a higher-level interface on top of the basics.
--
---
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_2123_510302313.1433937194273
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Op maandag 8 juni 2015 03:49:06 UTC+2 schreef Richard Smit=
h:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;b=
order-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div c=
lass=3D"gmail_quote"><div>Why would there be any extra storage? If you want=
to truncate prior to storing the value somewhere, then do so.</div><div><b=
r></div><div>And which would you prefer:</div><div><br></div><div>integer&l=
t;64> f(integer<32> a, integer<32> b) {</div><div> aut=
o x =3D a * a + b; // x is an integer<66>, but you don't really need =
to care</div><div> return x.fits_in<64>() ? x.truncate_to<64=
>() : 0;</div><div>}</div></div></div></div></blockquote><div><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div cla=
ss=3D"gmail_quote"><div><br></div><div>or</div><div><br></div><div>int64_t =
f(int32_t a, int32_t b) {</div><div> bool overflow =3D false;</div><d=
iv> int64_t r =3D add_overflow<int64_t>(<wbr>overflow, mul_over=
flow<int64_t>(<wbr>overflow, a, a), b);</div><div> return overf=
low ? 0 : r;</div><div>}</div></div></div></div></blockquote><div><br></div=
><div>The latter is likely to be faster then the former.</div><div>I'd go f=
or basic GCC-style interface: bool add_overflow(res, a, b);</div><div><br><=
/div><div>int64_t f(int32_t a, int32_t b) {</div><div> int64_t res;</=
div><div> return mul_overflow(res, a, a) || add_overflow(res, res, a)=
? 0 : res;</div><div>}</div><div><br></div><div>One can always write a hig=
her-level interface on top of the basics.</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" 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_2123_510302313.1433937194273--
------=_Part_2122_811786398.1433937194273--
.
Author: Richard Smith <richard@metafoo.co.uk>
Date: Wed, 10 Jun 2015 09:47:39 -0700
Raw View
--047d7b2e438c09983e05182ca2c4
Content-Type: text/plain; charset=UTF-8
On 10 Jun 2015 4:53 am, "Olaf van der Spek" <olafvdspek@gmail.com> wrote:
>
> Op maandag 8 juni 2015 03:49:06 UTC+2 schreef Richard Smith:
>>
>> Why would there be any extra storage? If you want to truncate prior to
storing the value somewhere, then do so.
>>
>> And which would you prefer:
>>
>> integer<64> f(integer<32> a, integer<32> b) {
>> auto x = a * a + b; // x is an integer<66>, but you don't really need
to care
>> return x.fits_in<64>() ? x.truncate_to<64>() : 0;
>> }
>
>
>>
>> or
>>
>> int64_t f(int32_t a, int32_t b) {
>> bool overflow = false;
>> int64_t r = add_overflow<int64_t>(overflow,
mul_overflow<int64_t>(overflow, a, a), b);
>> return overflow ? 0 : r;
>> }
>
>
> The latter is likely to be faster then the former.
A decent optimiser should be able to produce the same code for both.
> I'd go for basic GCC-style interface: bool add_overflow(res, a, b);
>
> int64_t f(int32_t a, int32_t b) {
> int64_t res;
> return mul_overflow(res, a, a) || add_overflow(res, res, a) ? 0 : res;
> }
>
> One can always write a higher-level interface on top of the basics.
>
> --
>
> ---
> 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/.
--
---
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/.
--047d7b2e438c09983e05182ca2c4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<p dir=3D"ltr">On 10 Jun 2015 4:53 am, "Olaf van der Spek" <<a=
href=3D"mailto:olafvdspek@gmail.com">olafvdspek@gmail.com</a>> wrote:<b=
r>
><br>
> Op maandag 8 juni 2015 03:49:06 UTC+2 schreef Richard Smith:<br>
>><br>
>> Why would there be any extra storage? If you want to truncate prio=
r to storing the value somewhere, then do so.<br>
>><br>
>> And which would you prefer:<br>
>><br>
>> integer<64> f(integer<32> a, integer<32> b) {<br=
>
>> =C2=A0 auto x =3D a * a + b; // x is an integer<66>, but you=
don't really need to care<br>
>> =C2=A0 return x.fits_in<64>() ? x.truncate_to<64>() : =
0;<br>
>> }<br>
><br>
><br>
>><br>
>> or<br>
>><br>
>> int64_t f(int32_t a, int32_t b) {<br>
>> =C2=A0 bool overflow =3D false;<br>
>> =C2=A0 int64_t r =3D add_overflow<int64_t>(overflow, mul_ove=
rflow<int64_t>(overflow, a, a), b);<br>
>> =C2=A0 return overflow ? 0 : r;<br>
>> }<br>
><br>
><br>
> The latter is likely to be faster then the former.</p>
<p dir=3D"ltr">A decent optimiser should be able to produce the same code f=
or both.</p>
<p dir=3D"ltr">> I'd go for basic GCC-style interface: bool add_over=
flow(res, a, b);<br>
><br>
> int64_t f(int32_t a, int32_t b) {<br>
> =C2=A0 int64_t res;<br>
> =C2=A0 return mul_overflow(res, a, a) || add_overflow(res, res, a) ? 0=
: res;<br>
> }<br>
><br>
> One can always write a higher-level interface on top of the basics.<br=
>
><br>
> -- <br>
><br>
> --- <br>
> You received this message because you are subscribed to the Google Gro=
ups "ISO C++ Standard - Future Proposals" group.<br>
> To unsubscribe from this group and stop receiving emails from it, send=
an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@isocpp.org</a>.<br>
> To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
> Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/g=
roup/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-propos=
als/</a>.<br>
</p>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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 />
--047d7b2e438c09983e05182ca2c4--
.
Author: Marian Klein <mkleinsoft@gmail.com>
Date: Thu, 11 Jun 2015 00:34:53 +0100
Raw View
On the side:
Probably the point of the previous email was on the operation inside,
but those two examples make no sense externally from outside the
function f:
How would the user of both function f on zero return value distinguish
between the valid sum of two numbers for example (0+0 or (-5)+(5)
)
and sum of two numbers with overflow? You always need to know the
carry flag when you need to chain the operation and you never need it
when you work in modular arithmetics.
We can always return std::tuple or std::pair<auto,bool> or the newly
proposed feature Multiple return value for this low level interface
See Matthew Fioravante commented in another thread
Re: [std-proposals] Re: Core Language feature: Multiple assignments
from multiple return values via tuple
template <typename IntegralL,typename IntegralR> [auto,bool]
add_carry(IntegralL l, IntegralR r);
I think we just need to standardise the wrappers around the gcc
built-in primitives as the low-level functions and to have higher
level wider (more than 64 bit) integer classes with two variants ,
one that represents the remainders of modulo 2^w (elements of modular
arithmetics) for compile-time specified bit-width w and with no
dynamic allocation (fully on the stack) and one true Natural Numbers
representing classes with dynamically run-time growing arbitrary width
like in python.
In my previous email I provided the stubs and I proposed two higher
level classes, now I am adding few more to discuss:
(all of the following would have also signed variants:)
1)
template <class wordT,int word_count=2>
struct composed_uint;
//fully on the stack implemented in terms of C array (wordT
[word_count] ) or std::array<wordT,word_count>
//alternative names: wide_uint or array_uint , unsigned_integer, what
name do you prefer?
//zero word count would be allowed and specialized into empty struct
for the purpose bellow in 5)
2) Dynamically allocated/resizeble memory with fixed size on the
stack (pimpl / one pointer only?)
template <class wordT,class Allocator = std::allocator<wordT> >
struct unbound_uint;
//dynamic allocation: sizeof(unbound_uint)==sizeof(void*);better to
implement in terms of single_pointer_vector from 5) rather than
std::vector
//alternative names natural_number or positive_natural_number, what
name do you prefer
//maybe we do not need this class , if 5) is preferred and more versatile
3)
For people who just need only a few extra bits (to serve as a carry
bit potentially) on top of built-in integer
and not the another big 64bit word I am proposing a shorter variant of
composed_uint:
template <class low_wordT,class high_wordT=low_wordT>
struct extended_uint;
So it can be instantiated as extended_uint<uint64_t,uint8_t>
4)
Alternative class signature of the first class ( template <class
wordT,int word_count=2> struct composed_uint; ) can be
template <int minimal_bit_width=2*sizeof(int)>
struct wide_uint;
//alternative names: unsigned_integer, uinteger, wide_uinteger ,
which one do you prefer?
where the actual bit width of the type would be calculated compile
time as the higher multiple of built-in int width by using
http://www.boost.org/doc/libs/1_54_0/libs/integer/doc/html/boost_integer/integer.html
What class signature do you prefer: 1) or 4) ?
5)
For unbound_uint I consider to have small count of words optimization
avoiding the memory allocation (similar to small string optimization
to put everything on the stack if under certain threshold size) , so
the least significant words are on the higher significant words are
dynamically allocated. There might be an option (edge case) not to
have anything on the stack. Notice in the following structure the
width of the integer on the stack can be changed as well compile time
(potentially having zero overhead for empty struct. The higher
value can be implemented in terms of vector (but on my system sizeof
(vector) is 24 bytes higher than sizeof(void*) 8 bytes) It looks the
vector keeps the pointer and the size and capacity information on the
stack. Or pointer to vector (with disadvantage of double allocation)
I prefer custom implementation of vector for this purpose to keep only
one pointer (potentially zero most of time, because it would be
allocated later on demand) on the stack so sizeof (custom_vector)==
sizeof(void*) .
Having just plain C pointer to dynamically allocated array of words
is another option. The first word can be reserved to keep the both
the count of the valid elements of the array (size) in the lower half
of the bits and the allocated size (=capacity) the higher half of the
bits.
template< class wordT , class low_uintT=composed_uint<wordT,0> ,class
Allocator = std::allocator<wordT> >
struct stack_optimized_unbound_uint //stack optimized (least
significant part used most frequently is on the stack)
{
low_uintT low; // can be resolved into empty struct if requested
//std::vector<wordT> high; // alternative1: not preferred
because sizeof( std::vector<wordT>) > sizeof(void*);
//std::vector<wordT> *high; //alternative 2: advantage: most
of the time can be zero pointer
//:disadvantage: double allocation one for vector and one for data
in the vector
single_pointer_vector<wordT> high; //alternative 3: can be
made sizeof (custom_vector)== sizeof(void*) ,
//if
higher words are rarely used we do not want the overhead of size,
capacity etc. on the stack
// wordT *high; //alternative 4: the
implementation of single_pointer_vector goes here directly as an
alternative
}
template <class wordT>
struct single_pointer_vector
{
wordT *data;// the first word data[0] would keep the size of the
array and capacity (half of the bits reserved for each)
}
What about copy behaviour for 2) and 5) ? Do we want
copy-on-write/shallow copy/ delayed deep copy, reference counting or
we should the user employ other techniques for such behaviour, such
as unique_pointer or just rely on move constructor?
Can you guys comment on those options above, please? And can you vote
for the names and class signatures as well?
Marian
On 10 June 2015 at 17:47, Richard Smith <richard@metafoo.co.uk> wrote:
> On 10 Jun 2015 4:53 am, "Olaf van der Spek" <olafvdspek@gmail.com> wrote:
>>
>> Op maandag 8 juni 2015 03:49:06 UTC+2 schreef Richard Smith:
>>>
>>> Why would there be any extra storage? If you want to truncate prior to
>>> storing the value somewhere, then do so.
>>>
>>> And which would you prefer:
>>>
>>> integer<64> f(integer<32> a, integer<32> b) {
>>> auto x = a * a + b; // x is an integer<66>, but you don't really need
>>> to care
>>> return x.fits_in<64>() ? x.truncate_to<64>() : 0;
>>> }
>>
>>
>>>
>>> or
>>>
>>> int64_t f(int32_t a, int32_t b) {
>>> bool overflow = false;
>>> int64_t r = add_overflow<int64_t>(overflow,
>>> mul_overflow<int64_t>(overflow, a, a), b);
>>> return overflow ? 0 : r;
>>> }
>>
>>
>> The latter is likely to be faster then the former.
>
> A decent optimiser should be able to produce the same code for both.
>
>> I'd go for basic GCC-style interface: bool add_overflow(res, a, b);
>>
>> int64_t f(int32_t a, int32_t b) {
>> int64_t res;
>> return mul_overflow(res, a, a) || add_overflow(res, res, a) ? 0 : res;
>> }
>>
>> One can always write a higher-level interface on top of the basics.
>>
>> --
>>
>> ---
>> 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/.
>
> --
>
> ---
> 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/.
--
---
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/.
.