Topic: Proposal: After the lifetime of an object data within


Author: christopher.hite.work@gmail.com
Date: Tue, 17 Apr 2018 04:47:03 -0700 (PDT)
Raw View
------=_Part_6386_947494493.1523965623858
Content-Type: multipart/alternative;
 boundary="----=_Part_6387_1574370862.1523965623858"

------=_Part_6387_1574370862.1523965623858
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Godbolt to compile code=20
<https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(j:1,lang:c%2B%2B,sourc=
e:'%23include+%3Cexperimental/optional%3E%0A%0A%23if+0%0Ausing+O+%3D+std::e=
xperimental::optional%3Cint%3E%3B%0A%23else%0A%0Astruct+O+%7B%0A++++bool+in=
ited+%3D+false%3B%0A++++int++value%3B%0A%0A++++~O()+%7B%0A++++++++if(inited=
)%0A++++++++++++inited+%3D+false%3B%0A++++%7D%0A%7D%3B%0A%0A%23endif%0A%0Av=
oid+destruct_optional_int(O%26+o)+%7B%0A++++o.~O()%3B++//+should+be+noop+%3=
F!!%0A%7D%0A%0Avoid+more_optional_int()+%7B%0A++++O+o%3B+++//+address+does+=
not+leak%0A%7D'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:33.333333333=
333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang600,fi=
lters:(b:'0',binary:'1',commentOnly:'0',demangle:'0',directives:'0',execute=
:'1',intel:'0',trim:'0'),lang:c%2B%2B,libs:!(),options:'-std%3Dc%2B%2B1z+-O=
3',source:1),l:'5',n:'0',o:'x86-64+clang+6.0.0+(Editor+%231,+Compiler+%231)=
+C%2B%2B',t:'0')),k:33.333333333333336,l:'4',n:'0',o:'',s:0,t:'0'),(g:!((h:=
output,i:(compiler:1,editor:1,wrap:'1'),l:'5',n:'0',o:'%231+with+x86-64+cla=
ng+6.0.0',t:'0')),k:33.33333333333333,l:'4',n:'0',o:'',s:0,t:'0')),l:'2',n:=
'0',o:'',t:'0')),version:4>
.. =20
#include <experimental/optional>

struct O {
   bool inited =3D false;
   int  value;

    ~O() {
       if(inited)
           inited =3D false;
   }
};

void destruct_optional_int(O& o) {
   o.~O(); // should be noop ?!
}

void more_optional_int() {
   O o;    // address does not leak
}

A few years ago I noticed boost::optional<int> deconstructing with a=20
branch.  One could argue such containers should be coded to have trivial=20
construction.  It seems the container std::optional that ships with gcc and=
=20
clang have fixed the issue.

I always thought there was room in the language spec to help optimization. =
=20
I'd like to propose something like this:

*After the lifetime of an object has ended data within its layout has=20
undefined value.*


Often the compiler can figure out that operations on such an object's=20
memory are undefined anyway, if the object existed on the stack or a delete=
=20
expression releases it to the heap.  However in cases where the memory is=
=20
from a pool or container are or the address leaks out of compilation scope,=
=20
it may not be able to prove this.

Note that the implementation can optimize further.  Once it is known the=20
memory of an object is undefined at a certain point, any previous stores to=
=20
that memory may be elided as long as they can be shown to have no side=20
effects up until that point.

It looks like gcc is assuming this is in the standard already.  Clang and=
=20
ICC do not.  Does anyone know if gcc is right?


--=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/1abb061a-5da1-4dec-af26-a2f0184543c3%40isocpp.or=
g.

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

<div dir=3D"ltr"><a href=3D"https://godbolt.org/#g:!((g:!((g:!((h:codeEdito=
r,i:(j:1,lang:c%2B%2B,source:&#39;%23include+%3Cexperimental/optional%3E%0A=
%0A%23if+0%0Ausing+O+%3D+std::experimental::optional%3Cint%3E%3B%0A%23else%=
0A%0Astruct+O+%7B%0A++++bool+inited+%3D+false%3B%0A++++int++value%3B%0A%0A+=
+++~O()+%7B%0A++++++++if(inited)%0A++++++++++++inited+%3D+false%3B%0A++++%7=
D%0A%7D%3B%0A%0A%23endif%0A%0Avoid+destruct_optional_int(O%26+o)+%7B%0A++++=
o.~O()%3B++//+should+be+noop+%3F!!%0A%7D%0A%0Avoid+more_optional_int()+%7B%=
0A++++O+o%3B+++//+address+does+not+leak%0A%7D&#39;),l:&#39;5&#39;,n:&#39;0&=
#39;,o:&#39;C%2B%2B+source+%231&#39;,t:&#39;0&#39;)),k:33.333333333333336,l=
:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;),(g:!((h:compiler=
,i:(compiler:clang600,filters:(b:&#39;0&#39;,binary:&#39;1&#39;,commentOnly=
:&#39;0&#39;,demangle:&#39;0&#39;,directives:&#39;0&#39;,execute:&#39;1&#39=
;,intel:&#39;0&#39;,trim:&#39;0&#39;),lang:c%2B%2B,libs:!(),options:&#39;-s=
td%3Dc%2B%2B1z+-O3&#39;,source:1),l:&#39;5&#39;,n:&#39;0&#39;,o:&#39;x86-64=
+clang+6.0.0+(Editor+%231,+Compiler+%231)+C%2B%2B&#39;,t:&#39;0&#39;)),k:33=
..333333333333336,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;=
),(g:!((h:output,i:(compiler:1,editor:1,wrap:&#39;1&#39;),l:&#39;5&#39;,n:&=
#39;0&#39;,o:&#39;%231+with+x86-64+clang+6.0.0&#39;,t:&#39;0&#39;)),k:33.33=
333333333333,l:&#39;4&#39;,n:&#39;0&#39;,o:&#39;&#39;,s:0,t:&#39;0&#39;)),l=
:&#39;2&#39;,n:&#39;0&#39;,o:&#39;&#39;,t:&#39;0&#39;)),version:4">Godbolt =
to compile code</a>.=C2=A0=C2=A0<div><div class=3D"prettyprint" style=3D"ba=
ckground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); borde=
r-style: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"p=
rettyprint"><div class=3D"subprettyprint"><div style=3D"color: #000000;back=
ground-color: #fffffe;font-family: Consolas, " liberation=3D"" mono",=3D"" =
courier,=3D"" monospace;font-weight:=3D"" normal;font-size:=3D"" 14px;line-=
height:=3D"" 19px;white-space:=3D"" pre;"=3D""><div><span style=3D"color: #=
0000ff;"><span style=3D"color: #800;" class=3D"styled-by-prettify">#include=
</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify">experimental</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">/</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">optional</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span></div><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"><br></span><div><span style=
=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">struct</span></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> O </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> =C2=A0 =C2=A0</span><span style=3D"color: #0000ff;"><span style=3D"color=
: #008;" class=3D"styled-by-prettify">bool</span></span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> inited </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: #0000ff;"><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">false</span></span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div><div><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=A0</sp=
an><span style=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"st=
yled-by-prettify">int</span></span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> =C2=A0value</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">;</span></div><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><div><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">~</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">O</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span></div><=
div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=A0 =C2=
=A0 =C2=A0 =C2=A0</span><span style=3D"color: #0000ff;"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">if</span></span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">inited</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">)</span></div><div><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0inited=
 </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 st=
yle=3D"color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">false</span></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">;</span></div><div><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> =C2=A0 =C2=A0</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span></div><div><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">};</span></div><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><div><span style=3D"color: #0000ff;"><span style=
=3D"color: #008;" class=3D"styled-by-prettify">void</span></span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify"> destruct_optional_int</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">O</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">&amp;</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> o</span><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: #660;" class=3D"styled-by=
-prettify">{</span></div><div><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> =C2=A0 =C2=A0o</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">.~</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">O</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>();</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008000;"><span style=3D"color: #800;" class=3D"sty=
led-by-prettify">// should be noop ?!</span></span></div><div><span style=
=3D"color: #800;" class=3D"styled-by-prettify">}</span></div><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br></span><div><span style=3D"=
color: #0000ff;"><span style=3D"color: #008;" class=3D"styled-by-prettify">=
void</span></span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> more_optional_int</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span>=
</div><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0O o</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0</span><span style=3D"color: #008000;"><span style=3D"color: #800=
;" class=3D"styled-by-prettify">// address does not leak</span></span></div=
><div><span style=3D"color: #800;" class=3D"styled-by-prettify">}</span></d=
iv></div></div></code></div><br><div>A few years ago I noticed boost::optio=
nal&lt;int&gt; deconstructing with a branch.=C2=A0 One could argue such con=
tainers should be coded to have trivial construction.=C2=A0 It seems the co=
ntainer std::optional that ships with gcc and clang have fixed the issue.<b=
r></div><div><div><br></div><div>I always thought there was room in the lan=
guage spec to help optimization.=C2=A0 I&#39;d like to propose something li=
ke this:</div><div><br></div><div><blockquote style=3D"margin: 0 0 0 40px; =
border: none; padding: 0px;"><div><b>After the lifetime of an object has en=
ded data within its layout has undefined value.</b><br></div></blockquote><=
/div><div><br></div><div>Often the compiler can figure out that operations =
on such an object&#39;s memory are undefined anyway, if the object existed =
on the stack or a delete expression releases it to the heap.=C2=A0 However =
in cases where the memory is from a pool or container are or the address le=
aks out of compilation scope, it may not be able to prove this.</div><div><=
br></div><div>Note that the implementation can optimize further.=C2=A0 Once=
 it is known the memory of an object is undefined at a certain point, any p=
revious stores to that memory may be elided as long as they can be shown to=
 have no side effects up until that point.</div><div><br></div><div>It look=
s like gcc is assuming this is in the standard already.=C2=A0 Clang and ICC=
 do not.=C2=A0 Does anyone know if gcc is right?<br><div><br></div><div><br=
></div></div></div></div></div>

<p></p>

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

------=_Part_6387_1574370862.1523965623858--

------=_Part_6386_947494493.1523965623858--

.