Topic: About "Relocation
Author: mihailnajdenov@gmail.com
Date: Sun, 22 Jul 2018 03:01:31 -0700 (PDT)
Raw View
------=_Part_7436_1762379853.1532253691292
Content-Type: multipart/alternative;
boundary="----=_Part_7437_805392397.1532253691293"
------=_Part_7437_805392397.1532253691293
Content-Type: text/plain; charset="UTF-8"
Hello, I am reading D1144R0
<https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-move-plus-destroy-draft-7.html>
and p1029r0
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
First that comes to my attention is the fact that the term 'relocation'
means different things in both proposals.
This is of no surprise considering the word 'relocation' is more or less a
synonym of 'move'.
Interestingly this is more true in C++ then human language as move in C++
> already means "establish yourself in a new place", where in human language
> this might not be the case.
If a concepts can mean different things, and is actually named with a
synonym of other, there seems to be a problem there.
Arguably 1144 does a better job of creating "real" new category -
move+destroy - but this category end up superficial and is introduced only
so that a "trivial" version of it can be introduced - move+don't_destroy.
On the other hand, 1029 names relocate just a special form of move.
No matter which one is "right", and I don't believe there is "right" here,
the point is, 'relocate' is not a good category in general:
- It is *not* self-explanatory like "move," "copy," "destroy," and
"swap" - all this are evident to even a non-programmer.
- It is expressed as a sub-category of move and not a new, separate
category.
One might argue, the second point is true for 'move' as well - it is a
> category of copy. This might be true technically, but not semantically -
> we have clear understating that, '
a copy, after which the object can not be used, is a move, and we have a
> word for it.
This is not the case with relocate - we don't have clear understanding what
> happens "after" - hence the two proposals - and we don't have a word for it
> - hence using a synonym for a word we already use.
What other thing that comes to my attention is that in actuality, there is
no new category, but instead a restoration of triviality.
This is, we can see that some (many, many) objects *become* trivial when
moved - after we move a unique_ptr, its destructor can be trivial.
We might express that as
~unique_ptr() [[trivial_after_move]]
{
delete _p;
_p = {};
}
Further, *other* functions can trivialize the object destruction:
We can define it as
~unique_ptr() [[trivial_after: release]];
or eventually, assuming the compiler reads Contracts
pointer unique_ptr::release() noexcept
{
// implementation
[[Ensures: trivial_destruction]]
}
unique_ptr& unique_ptr::operator=(unique_ptr&& o) noexcept
{
// implementation
[[Ensures: trivial_destruction]]
}
Also, not just the destructor can become trivial, but the copy constructor
as well, as it is the point with empty vector -
after it is cleared, and before it is reassigned, any vector is a trivial
type.
Taking it one step further we can imagine, we can decorate rvalue reference
> arguments (or create a contract) to say it will trivialize the object
> (until reassignment or pass by reference)
>
This might allow us expressing "destructive move" scenarios.
These are my observation so far. It seems instead of introducing a new
concept, we could express the idea in terms of triviality.
In a way this also takes care of the object lifetime debate as the object
lifetime is the same, but the compiler is free to use a trivial destructor
and is later free to optimize it away.
This freedom ends with reassign or pass by reference/pointer.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1cb7d63a-5373-49f3-a30c-3dfead9369cb%40isocpp.org.
------=_Part_7437_805392397.1532253691293
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hello, I am reading <a href=3D"https://quuxplusone.gi=
thub.io/blog/code/object-relocation-in-terms-of-move-plus-destroy-draft-7.h=
tml">D1144R0</a> and <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs=
/papers/2018/p1029r0.pdf">p1029r0</a></div><div><br></div><div>First that c=
omes to my attention is the fact that the term 'relocation' means d=
ifferent things in both proposals.</div><div>This is of no surprise conside=
ring the word 'relocation' is more or less a synonym of 'move&#=
39;.=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 20=
4, 204); border-left-width: 1px; border-left-style: solid;">Interestingly t=
his is more true in C++ then human language as move in C++ already means &q=
uot;establish yourself in a new place", where in human language this m=
ight not be the case.</blockquote><div><br></div><div>If a concepts can mea=
n different things, and is actually named with a synonym of other, there se=
ems to be a problem there.</div><div><br></div><div>Arguably 1144 does a be=
tter job of creating "real" new category - move+destroy - but thi=
s category end up superficial and is introduced only so that a "trivia=
l" version of it can be introduced - move+don't_destroy.=C2=A0</di=
v><div>On the other hand, 1029 names relocate just a special form of move.<=
/div><div><br></div><div>No matter which one is "right", and I do=
n't believe there is "right" here, the point is, 'relocat=
e' is not a good category in general:</div><ul><li>It is <i>not</i> sel=
f-explanatory like=C2=A0"move," "copy," "destroy,&=
quot; and "swap" -=C2=A0 all this are evident to even a non-progr=
ammer.</li><li>It is expressed as a sub-category of move and not a new, sep=
arate category.</li></ul><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204=
); border-left-width: 1px; border-left-style: solid;">One might argue, the =
second point is true for 'move' as well - it is a category of copy.=
This might be true technically, but not semantically=C2=A0 - we have clear=
understating that, '=C2=A0</blockquote><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color=
: rgb(204, 204, 204); border-left-width: 1px; border-left-style: solid;">a =
copy, after which the object can not be used, is a move, and we have a word=
for it. =C2=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"marg=
in: 0px 0px 0px 0.8ex; padding-left: 1ex; border-left-color: rgb(204, 204, =
204); border-left-width: 1px; border-left-style: solid;">This is not the ca=
se with relocate - we don't have clear understanding what happens "=
;after" - hence the two proposals - and we don't have a word for i=
t - hence using a synonym for a word we already use.</blockquote><div><br><=
/div><div>=C2=A0</div><div><br></div><div>What other thing that comes to my=
attention is that in actuality, there is no new category, but instead a re=
storation of triviality.=C2=A0</div><div><br></div><div>This is, we can see=
that some (many, many) objects <i>become</i> trivial when moved - after we=
move a unique_ptr, its destructor can be trivial.</div><div><br></div><div=
>We might express that as=C2=A0</div><div><br></div><font face=3D"courier n=
ew,monospace">~unique_ptr() [[trivial_after_move]] <br>{ <br>=C2=A0 delete =
_p; <br>=C2=A0 _p =3D {};<br></font><div><font face=3D"courier new,monospac=
e">}</font></div><div><font face=3D"courier new,monospace"><br></font></div=
><div>Further, <i>other</i> functions can trivialize the object destruction=
:</div><div><br></div><div>We can define it as<br></div><div><div style=3D"=
background-color: transparent; border-bottom-color: rgb(34, 34, 34); border=
-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; bord=
er-image-repeat: stretch; border-image-slice: 100%; border-image-source: no=
ne; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-left-=
style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34); b=
order-right-style: none; border-right-width: 0px; border-top-color: rgb(34,=
34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34, 34,=
34); font-family: &quot;Arial&quot;,&quot;Helvetica&quot;,=
sans-serif; font-size: 13px; font-style: normal; font-variant: normal; font=
-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px;=
margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; paddi=
ng-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; text-=
decoration: none; text-indent: 0px; text-transform: none; -webkit-text-stro=
ke-width: 0px; white-space: normal; word-spacing: 0px;"><br style=3D"backgr=
ound-attachment: scroll; background-clip: border-box; background-color: tra=
nsparent; background-image: none; background-origin: padding-box; backgroun=
d-position-x: 0%; background-position-y: 0%; background-repeat: repeat; bac=
kground-size: auto; border-bottom-color: rgb(34, 34, 34); border-bottom-sty=
le: none; border-bottom-width: 0px; border-image-outset: 0; border-image-re=
peat: stretch; border-image-slice: 100%; border-image-source: none; border-=
image-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none=
; border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right=
-style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); b=
order-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-=
family: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif;=
font-size: 13px; height: auto; margin-bottom: 0px; margin-left: 0px; margi=
n-right: 0px; margin-top: 0px; min-width: 0px; overflow: visible; overflow-=
x: visible; overflow-y: visible; padding-bottom: 0px; padding-left: 0px; pa=
dding-right: 0px; padding-top: 0px;"></div><font style=3D"background-color:=
transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: no=
ne; border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: =
stretch; border-image-slice: 100%; border-image-source: none; border-image-=
width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; bord=
er-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style=
: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-=
top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family=
: courier new,monospace; font-size: 13px; font-style: normal; font-variant:=
normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; marg=
in-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-botto=
m: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align=
: left; text-decoration: none; text-indent: 0px; text-transform: none; -web=
kit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">~uniqu=
e_ptr() [[trivial_after: release]];</font></div><div><font face=3D"courier =
new,monospace"></font><br></div><div>or eventually, assuming the compiler r=
eads Contracts</div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike=
></strike><br></div><div><font face=3D"courier new,monospace">pointer uniqu=
e_ptr::release() noexcept</font></div><div><font face=3D"courier new,monosp=
ace">{</font></div><div><font face=3D"courier new,monospace">=C2=A0 // impl=
ementation</font></div><div><font face=3D"courier new,monospace"><br></font=
></div><div><font face=3D"courier new,monospace">=C2=A0 [[Ensures: trivial_=
destruction]]</font></div><div><font face=3D"courier new,monospace">}</font=
></div><div><font face=3D"courier new,monospace"><br></font></div><div><fon=
t face=3D"courier new,monospace">unique_ptr& <span style=3D"display: in=
line !important; float: none; background-color: transparent; color: rgb(34,=
34, 34); font-family: courier new,monospace; font-size: 13px; font-style: =
normal; font-variant: normal; font-weight: 400; letter-spacing: normal; orp=
hans: 2; text-align: left; text-decoration: none; text-indent: 0px; text-tr=
ansform: none; -webkit-text-stroke-width: 0px; white-space: normal; word-sp=
acing: 0px;">unique_ptr::</span>operator=3D(unique_ptr&& o) noexcep=
t</font></div><div><font face=3D"courier new,monospace">{=C2=A0</font></div=
><div><font face=3D"courier new,monospace"><span style=3D"display: inline !=
important; float: none; background-color: transparent; color: rgb(34, 34, 3=
4); font-family: courier new,monospace; font-size: 13px; font-style: normal=
; font-variant: normal; font-weight: 400; letter-spacing: normal; orphans: =
2; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
0px;">=C2=A0 // implementation</span></font></div><div><font face=3D"couri=
er new,monospace"><span style=3D"display: inline !important; float: none; b=
ackground-color: transparent; color: rgb(34, 34, 34); font-family: courier =
new,monospace; font-size: 13px; font-style: normal; font-variant: normal; f=
ont-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; text=
-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-str=
oke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></font>=
</div><div><font face=3D"courier new,monospace"><span style=3D"text-align: =
left; color: rgb(34, 34, 34); text-transform: none; text-indent: 0px; lette=
r-spacing: normal; font-family: courier new,monospace; font-size: 13px; fon=
t-variant: normal; word-spacing: 0px; display: inline !important; white-spa=
ce: normal; orphans: 2; float: none; -webkit-text-stroke-width: 0px; backgr=
ound-color: transparent;"><span style=3D"display: inline !important; float:=
none; background-color: transparent; color: rgb(34, 34, 34); font-family: =
courier new,monospace; font-size: 13px; font-style: normal; font-variant: n=
ormal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=C2=A0 [[E=
nsures: trivial_destruction]]</span><b></b><i></i><u></u><sub></sub><sup></=
sup><strike></strike><br></span></font></div><div><font face=3D"courier new=
,monospace">}<br></font></div><div><font face=3D"courier new,monospace"><br=
></font></div><div>Also, not just the destructor can become trivial, but th=
e copy constructor as well, as it is the point with empty vector -=C2=A0</d=
iv><div>after it is cleared, and before it is reassigned, any vector is a t=
rivial type.</div><div><font face=3D"courier new,monospace"><br></font></di=
v><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; pad=
ding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-width: 1=
px; border-left-style: solid;">Taking it one step further we can imagine, w=
e can decorate rvalue reference arguments (or create a contract) to say it =
will trivialize the object (until reassignment or pass by reference)<br></b=
lockquote><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.=
8ex; padding-left: 1ex; border-left-color: rgb(204, 204, 204); border-left-=
width: 1px; border-left-style: solid;">This might allow us expressing "=
;destructive move" scenarios.</blockquote><div><br></div><div><br></di=
v><div>These are my observation so far. It seems instead of introducing a n=
ew concept, we could express the idea in terms of triviality.=C2=A0</div><d=
iv>In a way this also takes care of the object lifetime debate as the objec=
t lifetime is the same, but the compiler is free to use a trivial destructo=
r and is later free to optimize it away.</div><div>This freedom ends with r=
eassign or pass by reference/pointer.=C2=A0</div><div><br></div><div><br></=
div><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/1cb7d63a-5373-49f3-a30c-3dfead9369cb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1cb7d63a-5373-49f3-a30c-3dfead9369cb=
%40isocpp.org</a>.<br />
------=_Part_7437_805392397.1532253691293--
------=_Part_7436_1762379853.1532253691292--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 22 Jul 2018 07:49:42 -0700 (PDT)
Raw View
------=_Part_4145_1185590229.1532270982492
Content-Type: multipart/alternative;
boundary="----=_Part_4146_235248318.1532270982492"
------=_Part_4146_235248318.1532270982492
Content-Type: text/plain; charset="UTF-8"
On Sunday, July 22, 2018 at 6:01:31 AM UTC-4, mihailn...@gmail.com wrote:
>
> Hello, I am reading D1144R0
> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-move-plus-destroy-draft-7.html>
> and p1029r0
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
>
> First that comes to my attention is the fact that the term 'relocation'
> means different things in both proposals.
> This is of no surprise considering the word 'relocation' is more or less a
> synonym of 'move'.
>
> Interestingly this is more true in C++ then human language as move in C++
>> already means "establish yourself in a new place", where in human language
>> this might not be the case.
>
>
> If a concepts can mean different things, and is actually named with a
> synonym of other, there seems to be a problem there.
>
> Arguably 1144 does a better job of creating "real" new category -
> move+destroy - but this category end up superficial and is introduced only
> so that a "trivial" version of it can be introduced - move+don't_destroy.
> On the other hand, 1029 names relocate just a special form of move.
>
> No matter which one is "right", and I don't believe there is "right" here,
> the point is, 'relocate' is not a good category in general:
>
> - It is *not* self-explanatory like "move," "copy," "destroy," and
> "swap" - all this are evident to even a non-programmer.
> - It is expressed as a sub-category of move and not a new, separate
> category.
>
> Whatever it is named, we still need to be able to *do it*. The
performance benefit from being able to do it is vastly more important than
quibbling over what it gets called.
One might argue, the second point is true for 'move' as well - it is a
>> category of copy. This might be true technically, but not semantically -
>> we have clear understating that, '
>
> a copy, after which the object can not be used, is a move, and we have a
>> word for it.
>
> This is not the case with relocate - we don't have clear understanding
>> what happens "after" - hence the two proposals - and we don't have a word
>> for it - hence using a synonym for a word we already use.
>
>
>
>
> What other thing that comes to my attention is that in actuality, there is
> no new category, but instead a restoration of triviality.
>
But "triviality" is (and ought to be) a property of a *type*, not an object.
This is, we can see that some (many, many) objects *become* trivial when
> moved - after we move a unique_ptr, its destructor can be trivial.
>
But that's not really enough to do what we're trying to do. You also need
to be able to express the fact that the operation "memcpy+don't delete" is
exactly equivalent to a "move+delete" operation. Which means dealing with
the C++ object model ramifications of this. The destructor is only part of
that equation; it's the move constructor/assignment operator that puts the
object in a "cleared" state.
This is a property of the implementation of a type as a whole, not of any
one function. So applying an attribute to just one member doesn't make
sense.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8a616c65-0af8-4f6d-8860-ceb0e5e0771d%40isocpp.org.
------=_Part_4146_235248318.1532270982492
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, July 22, 2018 at 6:01:31 AM UTC-4, mihailn...@g=
mail.com 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>Hello, I am reading <a href=3D"https://quuxplusone.github.io/blog/co=
de/object-relocation-in-terms-of-move-plus-destroy-draft-7.html" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google=
..com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-re=
location-in-terms-of-move-plus-destroy-draft-7.html\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg';return true;" onclick=3D=
"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone=
..github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-move-plus-destroy-=
draft-7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAq=
uNdXWg';return true;">D1144R0</a> and <a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf" target=3D"_blank" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%=
3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp102=
9r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj6h9NquGMik=
A';return true;" onclick=3D"this.href=3D'http://www.google.com/url?=
q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2=
018%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj=
6h9NquGMikA';return true;">p1029r0</a></div><div><br></div><div>First t=
hat comes to my attention is the fact that the term 'relocation' me=
ans different things in both proposals.</div><div>This is of no surprise co=
nsidering the word 'relocation' is more or less a synonym of 'm=
ove'.=C2=A0</div><div><br></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid">Interestingly this is =
more true in C++ then human language as move in C++ already means "est=
ablish yourself in a new place", where in human language this might no=
t be the case.</blockquote><div><br></div><div>If a concepts can mean diffe=
rent things, and is actually named with a synonym of other, there seems to =
be a problem there.</div><div><br></div><div>Arguably 1144 does a better jo=
b of creating "real" new category - move+destroy - but this categ=
ory end up superficial and is introduced only so that a "trivial"=
version of it can be introduced - move+don't_destroy.=C2=A0</div><div>=
On the other hand, 1029 names relocate just a special form of move.</div><d=
iv><br></div><div>No matter which one is "right", and I don't=
believe there is "right" here, the point is, 'relocate' =
is not a good category in general:</div><ul><li>It is <i>not</i> self-expla=
natory like=C2=A0"move," "copy," "destroy," a=
nd "swap" -=C2=A0 all this are evident to even a non-programmer.<=
/li><li>It is expressed as a sub-category of move and not a new, separate c=
ategory.</li></ul></div></blockquote><div>Whatever it is named, we still ne=
ed to be able to <i>do it</i>. The performance benefit from being able to d=
o it is vastly more important than quibbling over what it gets called.<br><=
/div><div><br></div><div></div><blockquote class=3D"gmail_quote" style=3D"m=
argin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"=
><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px=
0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-=
width:1px;border-left-style:solid">One might argue, the second point is tru=
e for 'move' as well - it is a category of copy. This might be true=
technically, but not semantically=C2=A0 - we have clear understating that,=
'=C2=A0</blockquote><blockquote class=3D"gmail_quote" style=3D"margin:=
0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);borde=
r-left-width:1px;border-left-style:solid">a copy, after which the object ca=
n not be used, is a move, and we have a word for it. =C2=A0</blockquote><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-le=
ft:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;border-left=
-style:solid">This is not the case with relocate - we don't have clear =
understanding what happens "after" - hence the two proposals - an=
d we don't have a word for it - hence using a synonym for a word we alr=
eady use.</blockquote><div><br></div><div>=C2=A0</div><div><br></div><div>W=
hat other thing that comes to my attention is that in actuality, there is n=
o new category, but instead a restoration of triviality.=C2=A0</div></div><=
/blockquote><div><br></div><div>But "triviality" is (and ought to=
be) a property of a <i>type</i>, not an object.</div><div><br></div><block=
quote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-le=
ft: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>Thi=
s is, we can see that some (many, many) objects <i>become</i> trivial when =
moved - after we move a unique_ptr, its destructor can be trivial.</div></d=
iv></blockquote><div><br></div><div>But that's not really enough to do =
what we're trying to do. You also need to be able to express the fact t=
hat the operation "memcpy+don't delete" is exactly equivalent=
to a "move+delete" operation. Which means dealing with the C++ o=
bject model ramifications of this. The destructor is only part of that equa=
tion; it's the move constructor/assignment operator that puts the objec=
t in a "cleared" state.</div><div><br></div><div>This is a proper=
ty of the implementation of a type as a whole, not of any one function. So =
applying an attribute to just one member doesn't make sense.<br></div><=
br></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/8a616c65-0af8-4f6d-8860-ceb0e5e0771d%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/8a616c65-0af8-4f6d-8860-ceb0e5e0771d=
%40isocpp.org</a>.<br />
------=_Part_4146_235248318.1532270982492--
------=_Part_4145_1185590229.1532270982492--
.
Author: Arthur O'Dwyer <arthur.j.odwyer@gmail.com>
Date: Sun, 22 Jul 2018 22:10:11 -0700 (PDT)
Raw View
------=_Part_7967_742961364.1532322611678
Content-Type: multipart/alternative;
boundary="----=_Part_7968_1772753371.1532322611679"
------=_Part_7968_1772753371.1532322611679
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, mihailn...@gmail.com wrote:
>
> Hello, I am reading D1144R0=20
> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-mo=
ve-plus-destroy-draft-7.html>=20
> and p1029r0=20
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
>
> First that comes to my attention is the fact that the term 'relocation'=
=20
> means different things in both proposals.
> This is of no surprise considering the word 'relocation' is more or less =
a=20
> synonym of 'move'.=20
>
Basically agreed (although I also agree with Nicol that *naming* is less=20
important than *doing*). Some of the references in P1144 talk about=20
naming; you'll notice that both Qt and BSL actually call the operation by=
=20
the name "move", because they pre-date C++11 "move semantics." (And N1377=
=20
<https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-move=
-plus-destroy-draft-7.html#biblio-n1377>=20
indicates that C++0x really badly *wanted* to have destructive-move=20
semantics; the "construct, steal guts, but don't destroy" semantics that we=
=20
actually got in C++11 were a bit of a compromise, based on the fact that=20
they were actually implementable.) And in other languages without C++11's=
=20
baggage, such as Swift=20
<https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md#l=
ayout-and-properties-of-types>,=20
they actually have no problem using the word "move" for destructive-move!
But in C++, we definitely can't use the word "move"; it's occupied. So=20
P1144 uses the name "relocate", just like EASTL and Folly.
Interestingly this is more true in C++ then human language as move in C++=
=20
>> already means "establish yourself in a new place", where in human langua=
ge=20
>> this might not be the case.
>
>
> If a concepts can mean different things, and is actually named with a=20
> synonym of other, there seems to be a problem there.
>
> Arguably 1144 does a better job of creating "real" new category -=20
> move+destroy - but this category end up superficial and is introduced onl=
y=20
> so that a "trivial" version of it can be introduced - move+don't_destroy.
>
To be pedantically clear: You're using "move" here in its English sense,=20
not its C++ sense. Relocate means "move in the C++ sense, *plus* destroy";=
=20
or, if trivial, then the implementation is permitted to "*neither* move in=
=20
the C++ sense, *nor* destroy." The total number of [move-]constructions=20
and destructions must always remain balanced.
On the other hand, 1029 names relocate just a special form of move.
>
> No matter which one is "right", and I don't believe there is "right" here=
,=20
> the point is, 'relocate' is not a good category in general:
>
> - It is *not* self-explanatory like "move," "copy," "destroy," and=20
> "swap" - all this are evident to even a non-programmer.
> - It is expressed as a sub-category of move and not a new, separate=20
> category.
>
> I sympathize with your desire for words to mean what they mean in English=
,=20
but I think that ship sailed with C++11.
The meaning of "move" in C++ is *not* evident to a non-programmer. To the=
=20
extent that the non-programmer thinks they know what it means, they=20
probably imagine something like "relocate." However, we should also=20
remember that "move" and "copy" are not technically *verbs* in C++ =E2=80=
=94 they=20
are *adverbs*. We do not "copy" objects in C++; we "copy-construct" them=
=20
or "copy-assign" them. We do not "move" objects; we "move-construct" them=
=20
or "move-assign" them.
However, we do "swap" objects, and we do "relocate" objects.
We might even handwavily say that C++03 programs "copy-swap" objects=20
whereas C++11 programs "move-swap" them. C++11's `std::swap` relies on the=
=20
assumption that "copy-swap" and "move-swap" ought to have the same=20
observable effects.
What other thing that comes to my attention is that in actuality, there is=
=20
> no new category, but instead a restoration of triviality.=20
> This is, we can see that some (many, many) objects *become* trivial when=
=20
> moved - after we move a unique_ptr, its destructor can be trivial. [...]
>
(Pedantically: this is not the C++ definition of "trivial." I prefer to say=
=20
"no-op." But I see what you mean by the word in this context.)
Further, *other* functions can trivialize the object destruction: [...]
>
> pointer unique_ptr::release() noexcept [[ensures: trivial_destruction]]
> {
> // implementation
> }
>
This is an interesting and perhaps fruitful observation. For many=20
trivially relocatable types, the move constructor ensures that the object=
=20
is left in a state where destruction is a no-op.(*)
P1144 takes this observation and says, "Let's just skip the no-op=20
destruction, at the library level."
P1029 takes this observation and says, "Let's give a name to that state =E2=
=80=94=20
let's call it the default-constructed state."
You're saying, "Let's use Contracts to indicate to the compiler when an=20
object is in that state."
I think this is a philosophically sound idea; but I don't see how it would=
=20
really change anything for compiler-writers compared to what we have today.=
=20
I mean, already today we have
inline unique_ptr::~unique_ptr() {
if (m_ptr) delete m_ptr;
}
A sufficiently smart compiler *already knows* that unique_ptr::release()=20
always leaves the object with m_ptr=3D=3Dnullptr, and it *already knows* th=
at=20
if m_ptr=3D=3Dnullptr then the destructor is a no-op (because it can see th=
e=20
whole body of the inline destructor). Adding a contract like [[ensures:=20
trivial_destruction]] doesn't actually communicate any *new* information to=
=20
the compiler, does it?
And yet, compilers today *are* leaving performance on the table when it=20
comes to this kind of optimization; and implementing P1144 *does* get that=
=20
performance back. Suppose we went with something like this Contracts idea;=
=20
what would you expect codegen to look like, and what's your explanation for=
=20
why that codegen doesn't *already* happen?
=E2=80=93Arthur
(*) =E2=80=94 *Some* trivially relocatable types, such as a std::list whose=
=20
default-constructed state requires allocation, do *not* have this property.=
=20
For these types, destructing a moved-from object is *not* a no-op, because=
=20
it must deallocate the sentinel node. Another example would be a=20
"shared_ptr" with a copy constructor but no move constructor. P1144=20
optimizes these types nicely. I think your approach explicitly prohibits=20
optimizing them. I don't think P1029 ponders them at all, which means in=20
practice it wouldn't optimize them. For the purposes of exploring your=20
Contracts idea, I am okay with saying that we don't need to optimize such=
=20
types; but in this footnote I want to emphasize that they do exist and that=
=20
P1144 handles them well. ;)
--=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/2d3cdcf3-235e-424a-b64c-6d40f4792708%40isocpp.or=
g.
------=_Part_7968_1772753371.1532322611679
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, mihailn...@g=
mail.com 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>Hello, I am reading <a href=3D"https://quuxplusone.github.io/blog/co=
de/object-relocation-in-terms-of-move-plus-destroy-draft-7.html" target=3D"=
_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D'https://www.google=
..com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-re=
location-in-terms-of-move-plus-destroy-draft-7.html\x26sa\x3dD\x26sntz\x3d1=
\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg';return true;" onclick=3D=
"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone=
..github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-move-plus-destroy-=
draft-7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAq=
uNdXWg';return true;">D1144R0</a> and <a href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf" target=3D"_blank" rel=3D"nof=
ollow" onmousedown=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%=
3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp102=
9r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj6h9NquGMik=
A';return true;" onclick=3D"this.href=3D'http://www.google.com/url?=
q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2=
018%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj=
6h9NquGMikA';return true;">p1029r0</a></div><div><br></div><div>First t=
hat comes to my attention is the fact that the term 'relocation' me=
ans different things in both proposals.</div><div>This is of no surprise co=
nsidering the word 'relocation' is more or less a synonym of 'm=
ove'.=C2=A0</div></div></blockquote><div><br></div><div>Basically agree=
d (although I also agree with Nicol that <i>naming</i> is less important th=
an <i>doing</i>). =C2=A0Some of the references in P1144 talk about naming; =
you'll notice that both Qt and BSL actually call the operation by the n=
ame "move", because they pre-date C++11 "move semantics.&quo=
t; (And <a href=3D"https://quuxplusone.github.io/blog/code/object-relocatio=
n-in-terms-of-move-plus-destroy-draft-7.html#biblio-n1377">N1377</a> indica=
tes that C++0x really badly=C2=A0<i>wanted</i> to have destructive-move sem=
antics; the "construct, steal guts, but don't destroy" semant=
ics that we actually got in C++11 were a bit of a compromise, based on the =
fact that they were actually implementable.) =C2=A0And in other languages w=
ithout C++11's baggage, such as <a href=3D"https://github.com/apple/swi=
ft/blob/master/docs/ABIStabilityManifesto.md#layout-and-properties-of-types=
">Swift</a>, they actually have no problem using the word "move" =
for destructive-move!</div><div><br></div><div>But in C++, we definitely ca=
n't use the word "move"; it's occupied. So P1144 uses the=
name "relocate", just like EASTL and Folly.</div><div><br></div>=
<div><br></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><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width=
:1px;border-left-style:solid">Interestingly this is more true in C++ then h=
uman language as move in C++ already means "establish yourself in a ne=
w place", where in human language this might not be the case.</blockqu=
ote><div><br></div><div>If a concepts can mean different things, and is act=
ually named with a synonym of other, there seems to be a problem there.</di=
v><div><br></div><div>Arguably 1144 does a better job of creating "rea=
l" new category - move+destroy - but this category end up superficial =
and is introduced only so that a "trivial" version of it can be i=
ntroduced - move+don't_destroy.</div></div></blockquote><div><br></div>=
<div>To be pedantically clear: You're using "move" here in it=
s English sense, not its C++ sense. =C2=A0Relocate means "move in the =
C++ sense,=C2=A0<i>plus</i> destroy"; or, if trivial, then the impleme=
ntation is permitted to "<i>neither</i> move in the C++ sense, <i>nor<=
/i> destroy." =C2=A0The total number of [move-]constructions and destr=
uctions must always remain balanced.</div><div><br></div><div><br></div><bl=
ockquote 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>On the othe=
r hand, 1029 names relocate just a special form of move.</div><div><br></di=
v><div>No matter which one is "right", and I don't believe th=
ere is "right" here, the point is, 'relocate' is not a go=
od category in general:</div><ul><li>It is <i>not</i> self-explanatory like=
=C2=A0"move," "copy," "destroy," and "sw=
ap" -=C2=A0 all this are evident to even a non-programmer.</li><li>It =
is expressed as a sub-category of move and not a new, separate category.</l=
i></ul></div></blockquote><div>I sympathize with your desire for words to m=
ean what they mean in English, but I think that ship sailed with C++11.</di=
v><div>The meaning of "move" in C++ is <i>not</i> evident to a no=
n-programmer. To the extent that the non-programmer thinks they know what i=
t means, they probably imagine something like "relocate." However=
, we should also remember that "move" and "copy" are no=
t technically=C2=A0<i>verbs</i> in C++ =E2=80=94 they are <i>adverbs</i>. =
=C2=A0We do not "copy" objects in C++; we "copy-construct&qu=
ot; them or "copy-assign" them. =C2=A0We do not "move" =
objects; we "move-construct" them or "move-assign" them=
..</div><div>However, we do "swap" objects, and we do "reloca=
te" objects.</div><div>We might even handwavily say that C++03 program=
s "copy-swap" objects whereas C++11 programs "move-swap"=
; them. =C2=A0C++11's `std::swap` relies on the assumption that "c=
opy-swap" and "move-swap" ought to have the same observable =
effects.</div><div><br></div><div><br></div><div><br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #c=
cc solid;padding-left: 1ex;"><div dir=3D"ltr"><div>What other thing that co=
mes to my attention is that in actuality, there is no new category, but ins=
tead a restoration of triviality.=C2=A0</div><div>This is, we can see that =
some (many, many) objects <i>become</i> trivial when moved - after we move =
a unique_ptr, its destructor can be trivial. [...]</div></div></blockquote>=
<div><br></div><div>(Pedantically: this is not the C++ definition of "=
trivial." I prefer to say "no-op." But I see what you mean b=
y the word in this context.)</div><div><br></div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div>Further, <i>other</i> functions ca=
n trivialize the object destruction: [...]</div><div><b></b><i></i><u></u><=
sub></sub><sup></sup><strike></strike><br></div><div><font face=3D"courier =
new,monospace">pointer unique_ptr::release() noexcept=C2=A0</font><span sty=
le=3D"font-family: "courier new", monospace;">[[ensures: trivial_=
destruction]]</span></div><div><font face=3D"courier new,monospace">{</font=
></div><div><font face=3D"courier new,monospace">=C2=A0 // implementation</=
font></div><div><font face=3D"courier new,monospace">}</font></div></div></=
blockquote><div><br></div><div>This is an interesting and perhaps fruitful =
observation. =C2=A0For many trivially relocatable types, the move construct=
or ensures that the object is left in a state where destruction is a no-op.=
(*)</div><div>P1144 takes this observation and says, "Let's just s=
kip the no-op destruction, at the library level."</div><div>P1029 take=
s this observation and says, "Let's give a name to that state =E2=
=80=94 let's call it the default-constructed state."</div><div>You=
're saying, "Let's use Contracts to indicate to the compiler w=
hen an object is in that state."</div><div><br></div><div>I think this=
is a philosophically sound idea; but I don't see how it would really c=
hange anything for compiler-writers compared to what we have today. I mean,=
already today we have</div><div><br></div><div>=C2=A0 =C2=A0 inline unique=
_ptr::~unique_ptr() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (m_ptr) dele=
te m_ptr;</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>A sufficiently=
smart compiler <i>already knows</i> that unique_ptr::release() always leav=
es the object with m_ptr=3D=3Dnullptr, and it <i>already knows</i> that if =
m_ptr=3D=3Dnullptr then the destructor is a no-op (because it can see the w=
hole body of the inline destructor). =C2=A0Adding a contract like [[ensures=
: trivial_destruction]] doesn't actually communicate any <i>new</i> inf=
ormation to the compiler, does it?</div><div><br></div><div>And yet, compil=
ers today <i>are</i> leaving performance on the table when it comes to this=
kind of optimization; and implementing P1144 <i>does</i> get that performa=
nce back. Suppose we went with something like this Contracts idea; what wou=
ld you expect codegen to look like, and what's your explanation for why=
that codegen doesn't <i>already</i> happen?</div><div><br></div><div>=
=E2=80=93Arthur</div><div><br></div><div>(*) =E2=80=94 <i>Some</i> triviall=
y relocatable types, such as a std::list whose default-constructed state re=
quires allocation, do=C2=A0<i>not</i>=C2=A0have this property. For these ty=
pes, destructing a moved-from object is <i>not</i> a no-op, because it must=
deallocate the sentinel node. Another example would be a "shared_ptr&=
quot; with a copy constructor but no move constructor. P1144 optimizes thes=
e types nicely. I think your approach explicitly prohibits optimizing them.=
I don't think P1029 ponders them at all, which means in practice it wo=
uldn't optimize them. For the purposes of exploring your Contracts idea=
, I am okay with saying that we don't need to optimize such types; but =
in this footnote I want to emphasize that they do exist and that P1144 hand=
les them well. ;)</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2d3cdcf3-235e-424a-b64c-6d40f4792708%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2d3cdcf3-235e-424a-b64c-6d40f4792708=
%40isocpp.org</a>.<br />
------=_Part_7968_1772753371.1532322611679--
------=_Part_7967_742961364.1532322611678--
.
Author: mihailnajdenov@gmail.com
Date: Mon, 23 Jul 2018 03:36:26 -0700 (PDT)
Raw View
------=_Part_8162_2046653486.1532342186896
Content-Type: multipart/alternative;
boundary="----=_Part_8163_1963563471.1532342186897"
------=_Part_8163_1963563471.1532342186897
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Hello,
The point I was trying to make is that we are focused on a corner of a=20
concept that is much broader.
The broader concept is the fact that triviality is a state. Yes, it is per=
=20
type as far as C++ is concerned, but the objective reality is that it is a=
=20
state for all objects in std and many, many others.=20
Some objects never leave that state, other do, and very few in the world=20
are never in it.
We tap into that observation for the move+destroy/defaulted scenario, but=
=20
the broader observation holds in other cases as well.
The side effects of all this are two
First we could describe what are we are doing in terms of notions everybody=
=20
knows.
Second, we could look outside strictly move-destroy, as, on hand, other=20
actions (besides move) bring non-trivial objects in and out of=20
"triviality", and, on the other, not only destroy can take advantage of=20
"triviality", but copy as well
About the first point.=20
We *could* for instance name "trivially relocatable" "trivially=20
destructible after move" *, because untimely this is what we tap into. This=
=20
is clear both for the compiler and the user.=20
This free us from introducing the relocation concept altogether.=20
About the second point.=20
We *could *imagine a way to hint the compiler that vector<unique_ptr<int>>=
=20
v(1000000); could be both destroyed and copied (not just moved) around like=
=20
trivial type (until assigned or might-be-assigned).
We could imagine a cleared() vector or string, or released() smart pointer=
=20
to be treated as trivial type. Is the optimizer smart enough? I don't know.=
=20
To be clear, these are non-proposal observations.
=20
Thanks.
* Should this work with an object with no move ctor? Does not feel right,=
=20
TBH, but will not argue over that.
On Monday, July 23, 2018 at 8:10:11 AM UTC+3, Arthur O'Dwyer wrote:
>
> On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, mihailn...@gmail.com wrote:
>>
>> Hello, I am reading D1144R0=20
>> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-m=
ove-plus-destroy-draft-7.html>=20
>> and p1029r0=20
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
>>
>> First that comes to my attention is the fact that the term 'relocation'=
=20
>> means different things in both proposals.
>> This is of no surprise considering the word 'relocation' is more or less=
=20
>> a synonym of 'move'.=20
>>
>
> Basically agreed (although I also agree with Nicol that *naming* is less=
=20
> important than *doing*). Some of the references in P1144 talk about=20
> naming; you'll notice that both Qt and BSL actually call the operation by=
=20
> the name "move", because they pre-date C++11 "move semantics." (And N1377=
=20
> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-mo=
ve-plus-destroy-draft-7.html#biblio-n1377>=20
> indicates that C++0x really badly *wanted* to have destructive-move=20
> semantics; the "construct, steal guts, but don't destroy" semantics that =
we=20
> actually got in C++11 were a bit of a compromise, based on the fact that=
=20
> they were actually implementable.) And in other languages without C++11'=
s=20
> baggage, such as Swift=20
> <https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.md=
#layout-and-properties-of-types>,=20
> they actually have no problem using the word "move" for destructive-move!
>
> But in C++, we definitely can't use the word "move"; it's occupied. So=20
> P1144 uses the name "relocate", just like EASTL and Folly.
>
>
> Interestingly this is more true in C++ then human language as move in C++=
=20
>>> already means "establish yourself in a new place", where in human langu=
age=20
>>> this might not be the case.
>>
>>
>> If a concepts can mean different things, and is actually named with a=20
>> synonym of other, there seems to be a problem there.
>>
>> Arguably 1144 does a better job of creating "real" new category -=20
>> move+destroy - but this category end up superficial and is introduced on=
ly=20
>> so that a "trivial" version of it can be introduced - move+don't_destroy=
..
>>
>
> To be pedantically clear: You're using "move" here in its English sense,=
=20
> not its C++ sense. Relocate means "move in the C++ sense, *plus*=20
> destroy"; or, if trivial, then the implementation is permitted to "
> *neither* move in the C++ sense, *nor* destroy." The total number of=20
> [move-]constructions and destructions must always remain balanced.
>
>
> On the other hand, 1029 names relocate just a special form of move.
>>
>> No matter which one is "right", and I don't believe there is "right"=20
>> here, the point is, 'relocate' is not a good category in general:
>>
>> - It is *not* self-explanatory like "move," "copy," "destroy," and=20
>> "swap" - all this are evident to even a non-programmer.
>> - It is expressed as a sub-category of move and not a new, separate=
=20
>> category.
>>
>> I sympathize with your desire for words to mean what they mean in=20
> English, but I think that ship sailed with C++11.
> The meaning of "move" in C++ is *not* evident to a non-programmer. To the=
=20
> extent that the non-programmer thinks they know what it means, they=20
> probably imagine something like "relocate." However, we should also=20
> remember that "move" and "copy" are not technically *verbs* in C++ =E2=80=
=94 they=20
> are *adverbs*. We do not "copy" objects in C++; we "copy-construct" them=
=20
> or "copy-assign" them. We do not "move" objects; we "move-construct" the=
m=20
> or "move-assign" them.
> However, we do "swap" objects, and we do "relocate" objects.
> We might even handwavily say that C++03 programs "copy-swap" objects=20
> whereas C++11 programs "move-swap" them. C++11's `std::swap` relies on t=
he=20
> assumption that "copy-swap" and "move-swap" ought to have the same=20
> observable effects.
>
>
>
> What other thing that comes to my attention is that in actuality, there i=
s=20
>> no new category, but instead a restoration of triviality.=20
>> This is, we can see that some (many, many) objects *become* trivial when=
=20
>> moved - after we move a unique_ptr, its destructor can be trivial. [...]
>>
>
> (Pedantically: this is not the C++ definition of "trivial." I prefer to=
=20
> say "no-op." But I see what you mean by the word in this context.)
>
> Further, *other* functions can trivialize the object destruction: [...]
>>
>> pointer unique_ptr::release() noexcept [[ensures: trivial_destruction]]
>> {
>> // implementation
>> }
>>
>
> This is an interesting and perhaps fruitful observation. For many=20
> trivially relocatable types, the move constructor ensures that the object=
=20
> is left in a state where destruction is a no-op.(*)
> P1144 takes this observation and says, "Let's just skip the no-op=20
> destruction, at the library level."
> P1029 takes this observation and says, "Let's give a name to that state =
=E2=80=94=20
> let's call it the default-constructed state."
> You're saying, "Let's use Contracts to indicate to the compiler when an=
=20
> object is in that state."
>
> I think this is a philosophically sound idea; but I don't see how it woul=
d=20
> really change anything for compiler-writers compared to what we have toda=
y.=20
> I mean, already today we have
>
> inline unique_ptr::~unique_ptr() {
> if (m_ptr) delete m_ptr;
> }
>
> A sufficiently smart compiler *already knows* that unique_ptr::release()=
=20
> always leaves the object with m_ptr=3D=3Dnullptr, and it *already knows* =
that=20
> if m_ptr=3D=3Dnullptr then the destructor is a no-op (because it can see =
the=20
> whole body of the inline destructor). Adding a contract like [[ensures:=
=20
> trivial_destruction]] doesn't actually communicate any *new* information=
=20
> to the compiler, does it?
>
> And yet, compilers today *are* leaving performance on the table when it=
=20
> comes to this kind of optimization; and implementing P1144 *does* get=20
> that performance back. Suppose we went with something like this Contracts=
=20
> idea; what would you expect codegen to look like, and what's your=20
> explanation for why that codegen doesn't *already* happen?
>
> =E2=80=93Arthur
>
> (*) =E2=80=94 *Some* trivially relocatable types, such as a std::list who=
se=20
> default-constructed state requires allocation, do *not* have this=20
> property. For these types, destructing a moved-from object is *not* a=20
> no-op, because it must deallocate the sentinel node. Another example woul=
d=20
> be a "shared_ptr" with a copy constructor but no move constructor. P1144=
=20
> optimizes these types nicely. I think your approach explicitly prohibits=
=20
> optimizing them. I don't think P1029 ponders them at all, which means in=
=20
> practice it wouldn't optimize them. For the purposes of exploring your=20
> Contracts idea, I am okay with saying that we don't need to optimize such=
=20
> types; but in this footnote I want to emphasize that they do exist and th=
at=20
> P1144 handles them well. ;)
>
--=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/78f75c81-654f-4e36-8b60-a862a63f9c92%40isocpp.or=
g.
------=_Part_8163_1963563471.1532342186897
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div>Hello,</div><div><br></div><div>The point I was tryin=
g to make is that we are focused on a corner of a concept that is much broa=
der.</div><div><br></div><div>The broader concept is the fact that triviali=
ty is a state. Yes, it is per type as far as C++ is concerned, but the obje=
ctive reality is that it is a state for all objects in std and many, many o=
thers.=C2=A0</div><div>Some objects never leave that state, other do, and v=
ery few in the world are never in it.</div><div><br></div><div>We tap into =
that observation for the move+destroy/defaulted scenario, but the broader o=
bservation holds in other cases as well.</div><div><br></div><div>The side =
effects of all this are two</div><div><br></div><div>First we could describ=
e what are we are doing in terms of notions everybody knows.</div><div>Seco=
nd, we could look outside strictly move-destroy, as, on hand, other actions=
(besides move) bring non-trivial objects in and out of "triviality&qu=
ot;, and, on the other, not only destroy can take advantage of "trivia=
lity", but copy as well</div><div><br></div><div>About the first point=
..=C2=A0</div><div>We <i>could</i> for instance name "trivially relocat=
able" "trivially destructible after move" *, because untimel=
y this is what we tap into. This is clear both for the compiler and the use=
r.=C2=A0</div><div>This free us from introducing the relocation concept alt=
ogether.=C2=A0</div><div><br></div><div>About the second point.=C2=A0</div>=
<div>We <i>could </i>imagine a way to hint the compiler that <font face=3D"=
courier new,monospace">vector<unique_ptr<int>> v(1000000);</fon=
t><font face=3D"arial,sans-serif"> could be </font>both <font face=3D"arial=
,sans-serif">destroyed and copied (not just moved) around like trivial type=
(until assigned or might-be-assigned).</font></div><div><font face=3D"aria=
l,sans-serif">We could imagine a cleared() vector or string, or released() =
smart pointer to be treated as trivial type. Is the optimizer smart enough?=
I don't know.=C2=A0</font></div><div><font face=3D"courier new,monospa=
ce"></font><font face=3D"arial,sans-serif"></font><br></div><div><span styl=
e=3D"display: inline !important; float: none; background-color: transparent=
; color: rgb(34, 34, 34); font-family: "Arial","Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; orphans: 2; text-align: left; tex=
t-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-st=
roke-width: 0px; white-space: normal; word-spacing: 0px;">To be clear, thes=
e are non-proposal observations.</span></div><div>=C2=A0</div><div>Thanks.<=
/div><div><br></div><div>* Should this work with an object with no move cto=
r? Does not feel right, TBH, but will not argue over that.</div><div><br></=
div><br>On Monday, July 23, 2018 at 8:10:11 AM UTC+3, Arthur O'Dwyer wr=
ote:<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">On Sunday=
, July 22, 2018 at 3:01:31 AM UTC-7, <a>mihailn...@gmail.com</a> wrote:<blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Hello, I am readi=
ng <a onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dhttps=
%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-o=
f-move-plus-destroy-draft-7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG9=
3lHK8KDaaxON8x1hnYAquNdXWg';return true;" onclick=3D"this.href=3D'h=
ttps://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2=
Fcode%2Fobject-relocation-in-terms-of-move-plus-destroy-draft-7.html\x26sa\=
x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg';return =
true;" href=3D"https://quuxplusone.github.io/blog/code/object-relocation-in=
-terms-of-move-plus-destroy-draft-7.html" target=3D"_blank" rel=3D"nofollow=
">D1144R0</a> and <a onmousedown=3D"this.href=3D'http://www.google.com/=
url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers=
%2F2018%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvD=
s0sj6h9NquGMikA';return true;" onclick=3D"this.href=3D'http://www.g=
oogle.com/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdoc=
s%2Fpapers%2F2018%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQ=
gX7XCXIEvDs0sj6h9NquGMikA';return true;" href=3D"http://www.open-std.or=
g/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf" target=3D"_blank" rel=3D"nof=
ollow">p1029r0</a></div><div><br></div><div>First that comes to my attentio=
n is the fact that the term 'relocation' means different things in =
both proposals.</div><div>This is of no surprise considering the word '=
relocation' is more or less a synonym of 'move'.=C2=A0</div></d=
iv></blockquote><div><br></div><div>Basically agreed (although I also agree=
with Nicol that <i>naming</i> is less important than <i>doing</i>). =C2=A0=
Some of the references in P1144 talk about naming; you'll notice that b=
oth Qt and BSL actually call the operation by the name "move", be=
cause they pre-date C++11 "move semantics." (And <a onmousedown=
=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplus=
one.github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-move-plus-destr=
oy-draft-7.html%23biblio-n1377\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGGDm=
j3MZCPccNDQDN1yZMpM6N1kw';return true;" onclick=3D"this.href=3D'htt=
ps://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fc=
ode%2Fobject-relocation-in-terms-of-move-plus-destroy-draft-7.html%23biblio=
-n1377\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGGDmj3MZCPccNDQDN1yZMpM6N1kw=
';return true;" href=3D"https://quuxplusone.github.io/blog/code/object-=
relocation-in-terms-of-move-plus-destroy-draft-7.html#biblio-n1377" target=
=3D"_blank" rel=3D"nofollow">N1377</a> indicates that C++0x really badly=C2=
=A0<i>wanted</i> to have destructive-move semantics; the "construct, s=
teal guts, but don't destroy" semantics that we actually got in C+=
+11 were a bit of a compromise, based on the fact that they were actually i=
mplementable.) =C2=A0And in other languages without C++11's baggage, su=
ch as <a onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dht=
tps%3A%2F%2Fgithub.com%2Fapple%2Fswift%2Fblob%2Fmaster%2Fdocs%2FABIStabilit=
yManifesto.md%23layout-and-properties-of-types\x26sa\x3dD\x26sntz\x3d1\x26u=
sg\x3dAFQjCNFtZK5MnJ1twYNFbXEhBzAyJvBJ5Q';return true;" onclick=3D"this=
..href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fapp=
le%2Fswift%2Fblob%2Fmaster%2Fdocs%2FABIStabilityManifesto.md%23layout-and-p=
roperties-of-types\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFtZK5MnJ1twYNFbX=
EhBzAyJvBJ5Q';return true;" href=3D"https://github.com/apple/swift/blob=
/master/docs/ABIStabilityManifesto.md#layout-and-properties-of-types" targe=
t=3D"_blank" rel=3D"nofollow">Swift</a>, they actually have no problem usin=
g the word "move" for destructive-move!</div><div><br></div><div>=
But in C++, we definitely can't use the word "move"; it's=
occupied. So P1144 uses the name "relocate", just like EASTL and=
Folly.</div><div><br></div><div><br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><div></div><blockquote class=3D"gmail_quote" style=
=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;border-left-color:rgb(204,204=
,204);border-left-width:1px;border-left-style:solid">Interestingly this is =
more true in C++ then human language as move in C++ already means "est=
ablish yourself in a new place", where in human language this might no=
t be the case.</blockquote><div><br></div><div>If a concepts can mean diffe=
rent things, and is actually named with a synonym of other, there seems to =
be a problem there.</div><div><br></div><div>Arguably 1144 does a better jo=
b of creating "real" new category - move+destroy - but this categ=
ory end up superficial and is introduced only so that a "trivial"=
version of it can be introduced - move+don't_destroy.</div></div></blo=
ckquote><div><br></div><div>To be pedantically clear: You're using &quo=
t;move" here in its English sense, not its C++ sense. =C2=A0Relocate m=
eans "move in the C++ sense,=C2=A0<i>plus</i> destroy"; or, if tr=
ivial, then the implementation is permitted to "<i>neither</i> move in=
the C++ sense, <i>nor</i> destroy." =C2=A0The total number of [move-]=
constructions and destructions must always remain balanced.</div><div><br><=
/div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><div>On the other hand, 1029 names relocate just a special form of move.<=
/div><div><br></div><div>No matter which one is "right", and I do=
n't believe there is "right" here, the point is, 'relocat=
e' is not a good category in general:</div><ul><li>It is <i>not</i> sel=
f-explanatory like=C2=A0"move," "copy," "destroy,&=
quot; and "swap" -=C2=A0 all this are evident to even a non-progr=
ammer.</li><li>It is expressed as a sub-category of move and not a new, sep=
arate category.</li></ul></div></blockquote><div>I sympathize with your des=
ire for words to mean what they mean in English, but I think that ship sail=
ed with C++11.</div><div>The meaning of "move" in C++ is <i>not</=
i> evident to a non-programmer. To the extent that the non-programmer think=
s they know what it means, they probably imagine something like "reloc=
ate." However, we should also remember that "move" and "=
;copy" are not technically=C2=A0<i>verbs</i> in C++ =E2=80=94 they are=
<i>adverbs</i>. =C2=A0We do not "copy" objects in C++; we "=
copy-construct" them or "copy-assign" them. =C2=A0We do not =
"move" objects; we "move-construct" them or "move-=
assign" them.</div><div>However, we do "swap" objects, and w=
e do "relocate" objects.</div><div>We might even handwavily say t=
hat C++03 programs "copy-swap" objects whereas C++11 programs &qu=
ot;move-swap" them. =C2=A0C++11's `std::swap` relies on the assump=
tion that "copy-swap" and "move-swap" ought to have the=
same observable effects.</div><div><br></div><div><br></div><div><br></div=
><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;bord=
er-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>What other t=
hing that comes to my attention is that in actuality, there is no new categ=
ory, but instead a restoration of triviality.=C2=A0</div><div>This is, we c=
an see that some (many, many) objects <i>become</i> trivial when moved - af=
ter we move a unique_ptr, its destructor can be trivial. [...]</div></div><=
/blockquote><div><br></div><div>(Pedantically: this is not the C++ definiti=
on of "trivial." I prefer to say "no-op." But I see wha=
t you mean by the word in this context.)</div><div><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div>Further, <i>other</i> funct=
ions can trivialize the object destruction: [...]</div><div><b></b><i></i><=
u></u><sub></sub><sup></sup><strike></strike><br></div><div><font face=3D"c=
ourier new,monospace">pointer unique_ptr::release() noexcept=C2=A0</font><s=
pan style=3D"font-family:"courier new",monospace">[[ensures: triv=
ial_destruction]]</span></div><div><font face=3D"courier new,monospace">{</=
font></div><div><font face=3D"courier new,monospace">=C2=A0 // implementati=
on</font></div><div><font face=3D"courier new,monospace">}</font></div></di=
v></blockquote><div><br></div><div>This is an interesting and perhaps fruit=
ful observation. =C2=A0For many trivially relocatable types, the move const=
ructor ensures that the object is left in a state where destruction is a no=
-op.(*)</div><div>P1144 takes this observation and says, "Let's ju=
st skip the no-op destruction, at the library level."</div><div>P1029 =
takes this observation and says, "Let's give a name to that state =
=E2=80=94 let's call it the default-constructed state."</div><div>=
You're saying, "Let's use Contracts to indicate to the compile=
r when an object is in that state."</div><div><br></div><div>I think t=
his is a philosophically sound idea; but I don't see how it would reall=
y change anything for compiler-writers compared to what we have today. I me=
an, already today we have</div><div><br></div><div>=C2=A0 =C2=A0 inline uni=
que_ptr::~unique_ptr() {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (m_ptr) d=
elete m_ptr;</div><div>=C2=A0 =C2=A0 }</div><div><br></div><div>A sufficien=
tly smart compiler <i>already knows</i> that unique_ptr::release() always l=
eaves the object with m_ptr=3D=3Dnullptr, and it <i>already knows</i> that =
if m_ptr=3D=3Dnullptr then the destructor is a no-op (because it can see th=
e whole body of the inline destructor). =C2=A0Adding a contract like [[ensu=
res: trivial_destruction]] doesn't actually communicate any <i>new</i> =
information to the compiler, does it?</div><div><br></div><div>And yet, com=
pilers today <i>are</i> leaving performance on the table when it comes to t=
his kind of optimization; and implementing P1144 <i>does</i> get that perfo=
rmance back. Suppose we went with something like this Contracts idea; what =
would you expect codegen to look like, and what's your explanation for =
why that codegen doesn't <i>already</i> happen?</div><div><br></div><di=
v>=E2=80=93Arthur</div><div><br></div><div>(*) =E2=80=94 <i>Some</i> trivia=
lly relocatable types, such as a std::list whose default-constructed state =
requires allocation, do=C2=A0<i>not</i>=C2=A0have this property. For these =
types, destructing a moved-from object is <i>not</i> a no-op, because it mu=
st deallocate the sentinel node. Another example would be a "shared_pt=
r" with a copy constructor but no move constructor. P1144 optimizes th=
ese types nicely. I think your approach explicitly prohibits optimizing the=
m. I don't think P1029 ponders them at all, which means in practice it =
wouldn't optimize them. For the purposes of exploring your Contracts id=
ea, I am okay with saying that we don't need to optimize such types; bu=
t in this footnote I want to emphasize that they do exist and that P1144 ha=
ndles them well. ;)</div></div></blockquote></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/78f75c81-654f-4e36-8b60-a862a63f9c92%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/78f75c81-654f-4e36-8b60-a862a63f9c92=
%40isocpp.org</a>.<br />
------=_Part_8163_1963563471.1532342186897--
------=_Part_8162_2046653486.1532342186896--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 23 Jul 2018 06:56:50 -0700 (PDT)
Raw View
------=_Part_8113_1026738434.1532354210811
Content-Type: multipart/alternative;
boundary="----=_Part_8114_1359204786.1532354210812"
------=_Part_8114_1359204786.1532354210812
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Monday, July 23, 2018 at 6:36:27 AM UTC-4, mihailn...@gmail.com wrote:
>
> Hello,
>
> The point I was trying to make is that we are focused on a corner of a=20
> concept that is much broader.
>
> The broader concept is the fact that triviality is a state. Yes, it is pe=
r=20
> type as far as C++ is concerned, but the objective reality is that it is =
a=20
> state for all objects in std and many, many others.=20
> Some objects never leave that state, other do, and very few in the world=
=20
> are never in it.
>
One problem I see here is the question of what "triviality" means. There=20
are many kinds of trivial operations. Some types are trivial; others are=20
only trivially copyable. And so forth.
Which trivial operations can be ephemeral in this way? Is there a way to=20
test when an object has which trivial operations?
I have a nice function for performing bytewise-copies of objects and=20
arrays, which is guarded by `is_trivially_copyable<T>`. That is a good way=
=20
to catch errors. With P1144, I can simply update that to an=20
`is_trivially_relocatable<T>`. What you're suggesting would make it=20
impossible to have any compile-time guards on the function.
We tap into that observation for the move+destroy/defaulted scenario, but=
=20
> the broader observation holds in other cases as well.
>
> The side effects of all this are two
>
> First we could describe what are we are doing in terms of notions=20
> everybody knows.
> Second, we could look outside strictly move-destroy, as, on hand, other=
=20
> actions (besides move) bring non-trivial objects in and out of=20
> "triviality", and, on the other, not only destroy can take advantage of=
=20
> "triviality", but copy as well
>
> About the first point.=20
> We *could* for instance name "trivially relocatable" "trivially=20
> destructible after move" *, because untimely this is what we tap into. Th=
is=20
> is clear both for the compiler and the user.=20
> This free us from introducing the relocation concept altogether.
>
But as Arthur noted, this definition would exempt an entire category of=20
objects like `std::list`, where move does not leave them in a "trivial"=20
state. The P1144 definition of relocation is that "move+destroy" is=20
equivalent to "memcpy+drop". That's not the same thing as declaring that=20
movement leaves the object in a "trivial state".
About the second point.=20
> We *could *imagine a way to hint the compiler that vector<unique_ptr<int>=
>=20
> v(1000000); could be both destroyed and copied (not just moved) around=20
> like trivial type (until assigned or might-be-assigned).
> We could imagine a cleared() vector or string, or released() smart pointe=
r=20
> to be treated as trivial type. Is the optimizer smart enough? I don't kno=
w.=20
>
> To be clear, these are non-proposal observations.
> =20
> Thanks.
>
> * Should this work with an object with no move ctor? Does not feel right,=
=20
> TBH, but will not argue over that.
>
>
> On Monday, July 23, 2018 at 8:10:11 AM UTC+3, Arthur O'Dwyer wrote:
>>
>> On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, mihailn...@gmail.com wrote=
:
>>>
>>> Hello, I am reading D1144R0=20
>>> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-=
move-plus-destroy-draft-7.html>=20
>>> and p1029r0=20
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
>>>
>>> First that comes to my attention is the fact that the term 'relocation'=
=20
>>> means different things in both proposals.
>>> This is of no surprise considering the word 'relocation' is more or les=
s=20
>>> a synonym of 'move'.=20
>>>
>>
>> Basically agreed (although I also agree with Nicol that *naming* is less=
=20
>> important than *doing*). Some of the references in P1144 talk about=20
>> naming; you'll notice that both Qt and BSL actually call the operation b=
y=20
>> the name "move", because they pre-date C++11 "move semantics." (And N137=
7=20
>> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-m=
ove-plus-destroy-draft-7.html#biblio-n1377>=20
>> indicates that C++0x really badly *wanted* to have destructive-move=20
>> semantics; the "construct, steal guts, but don't destroy" semantics that=
we=20
>> actually got in C++11 were a bit of a compromise, based on the fact that=
=20
>> they were actually implementable.) And in other languages without C++11=
's=20
>> baggage, such as Swift=20
>> <https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.m=
d#layout-and-properties-of-types>,=20
>> they actually have no problem using the word "move" for destructive-move=
!
>>
>> But in C++, we definitely can't use the word "move"; it's occupied. So=
=20
>> P1144 uses the name "relocate", just like EASTL and Folly.
>>
>>
>> Interestingly this is more true in C++ then human language as move in C+=
+=20
>>>> already means "establish yourself in a new place", where in human lang=
uage=20
>>>> this might not be the case.
>>>
>>>
>>> If a concepts can mean different things, and is actually named with a=
=20
>>> synonym of other, there seems to be a problem there.
>>>
>>> Arguably 1144 does a better job of creating "real" new category -=20
>>> move+destroy - but this category end up superficial and is introduced o=
nly=20
>>> so that a "trivial" version of it can be introduced - move+don't_destro=
y.
>>>
>>
>> To be pedantically clear: You're using "move" here in its English sense,=
=20
>> not its C++ sense. Relocate means "move in the C++ sense, *plus*=20
>> destroy"; or, if trivial, then the implementation is permitted to "
>> *neither* move in the C++ sense, *nor* destroy." The total number of=20
>> [move-]constructions and destructions must always remain balanced.
>>
>>
>> On the other hand, 1029 names relocate just a special form of move.
>>>
>>> No matter which one is "right", and I don't believe there is "right"=20
>>> here, the point is, 'relocate' is not a good category in general:
>>>
>>> - It is *not* self-explanatory like "move," "copy," "destroy," and=
=20
>>> "swap" - all this are evident to even a non-programmer.
>>> - It is expressed as a sub-category of move and not a new, separate=
=20
>>> category.
>>>
>>> I sympathize with your desire for words to mean what they mean in=20
>> English, but I think that ship sailed with C++11.
>> The meaning of "move" in C++ is *not* evident to a non-programmer. To=20
>> the extent that the non-programmer thinks they know what it means, they=
=20
>> probably imagine something like "relocate." However, we should also=20
>> remember that "move" and "copy" are not technically *verbs* in C++ =E2=
=80=94=20
>> they are *adverbs*. We do not "copy" objects in C++; we=20
>> "copy-construct" them or "copy-assign" them. We do not "move" objects; =
we=20
>> "move-construct" them or "move-assign" them.
>> However, we do "swap" objects, and we do "relocate" objects.
>> We might even handwavily say that C++03 programs "copy-swap" objects=20
>> whereas C++11 programs "move-swap" them. C++11's `std::swap` relies on =
the=20
>> assumption that "copy-swap" and "move-swap" ought to have the same=20
>> observable effects.
>>
>>
>>
>> What other thing that comes to my attention is that in actuality, there=
=20
>>> is no new category, but instead a restoration of triviality.=20
>>> This is, we can see that some (many, many) objects *become* trivial=20
>>> when moved - after we move a unique_ptr, its destructor can be trivial.=
=20
>>> [...]
>>>
>>
>> (Pedantically: this is not the C++ definition of "trivial." I prefer to=
=20
>> say "no-op." But I see what you mean by the word in this context.)
>>
>> Further, *other* functions can trivialize the object destruction: [...]
>>>
>>> pointer unique_ptr::release() noexcept [[ensures: trivial_destruction]]
>>> {
>>> // implementation
>>> }
>>>
>>
>> This is an interesting and perhaps fruitful observation. For many=20
>> trivially relocatable types, the move constructor ensures that the objec=
t=20
>> is left in a state where destruction is a no-op.(*)
>> P1144 takes this observation and says, "Let's just skip the no-op=20
>> destruction, at the library level."
>> P1029 takes this observation and says, "Let's give a name to that state =
=E2=80=94=20
>> let's call it the default-constructed state."
>> You're saying, "Let's use Contracts to indicate to the compiler when an=
=20
>> object is in that state."
>>
>> I think this is a philosophically sound idea; but I don't see how it=20
>> would really change anything for compiler-writers compared to what we ha=
ve=20
>> today. I mean, already today we have
>>
>> inline unique_ptr::~unique_ptr() {
>> if (m_ptr) delete m_ptr;
>> }
>>
>> A sufficiently smart compiler *already knows* that unique_ptr::release()=
=20
>> always leaves the object with m_ptr=3D=3Dnullptr, and it *already knows*=
=20
>> that if m_ptr=3D=3Dnullptr then the destructor is a no-op (because it ca=
n see=20
>> the whole body of the inline destructor). Adding a contract like=20
>> [[ensures: trivial_destruction]] doesn't actually communicate any *new*=
=20
>> information to the compiler, does it?
>>
>> And yet, compilers today *are* leaving performance on the table when it=
=20
>> comes to this kind of optimization; and implementing P1144 *does* get=20
>> that performance back. Suppose we went with something like this Contract=
s=20
>> idea; what would you expect codegen to look like, and what's your=20
>> explanation for why that codegen doesn't *already* happen?
>>
>> =E2=80=93Arthur
>>
>> (*) =E2=80=94 *Some* trivially relocatable types, such as a std::list wh=
ose=20
>> default-constructed state requires allocation, do *not* have this=20
>> property. For these types, destructing a moved-from object is *not* a=20
>> no-op, because it must deallocate the sentinel node. Another example wou=
ld=20
>> be a "shared_ptr" with a copy constructor but no move constructor. P1144=
=20
>> optimizes these types nicely. I think your approach explicitly prohibits=
=20
>> optimizing them. I don't think P1029 ponders them at all, which means in=
=20
>> practice it wouldn't optimize them. For the purposes of exploring your=
=20
>> Contracts idea, I am okay with saying that we don't need to optimize suc=
h=20
>> types; but in this footnote I want to emphasize that they do exist and t=
hat=20
>> P1144 handles them well. ;)
>>
>
--=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/67b035da-5306-49c1-8058-5e647a5ff654%40isocpp.or=
g.
------=_Part_8114_1359204786.1532354210812
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, July 23, 2018 at 6:36:27 AM UTC-4, mihailn...@g=
mail.com 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>Hello,</div><div><br></div><div>The point I was trying to make is th=
at we are focused on a corner of a concept that is much broader.</div><div>=
<br></div><div>The broader concept is the fact that triviality is a state. =
Yes, it is per type as far as C++ is concerned, but the objective reality i=
s that it is a state for all objects in std and many, many others.=C2=A0</d=
iv><div>Some objects never leave that state, other do, and very few in the =
world are never in it.</div></div></blockquote><div><br></div><div>One prob=
lem I see here is the question of what "triviality" means. There =
are many kinds of trivial operations. Some types are trivial; others are on=
ly trivially copyable. And so forth.</div><div><br></div><div>Which trivial=
operations can be ephemeral in this way? Is there a way to test when an ob=
ject has which trivial operations?</div><div><br></div><div>I have a nice f=
unction for performing bytewise-copies of objects and arrays, which is guar=
ded by `is_trivially_copyable<T>`. That is a good way to catch errors=
.. With P1144, I can simply update that to an `is_trivially_relocatable<T=
>`. What you're suggesting would make it impossible to have any comp=
ile-time guards on the function.</div><div><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;"><div dir=3D"ltr"><div></div><div>We tap into that ob=
servation for the move+destroy/defaulted scenario, but the broader observat=
ion holds in other cases as well.</div><div><br></div><div>The side effects=
of all this are two</div><div><br></div><div>First we could describe what =
are we are doing in terms of notions everybody knows.</div><div>Second, we =
could look outside strictly move-destroy, as, on hand, other actions (besid=
es move) bring non-trivial objects in and out of "triviality", an=
d, on the other, not only destroy can take advantage of "triviality&qu=
ot;, but copy as well</div><div><br></div><div>About the first point.=C2=A0=
</div><div>We <i>could</i> for instance name "trivially relocatable&qu=
ot; "trivially destructible after move" *, because untimely this =
is what we tap into. This is clear both for the compiler and the user.=C2=
=A0</div><div>This free us from introducing the relocation concept altogeth=
er.</div></div></blockquote><div><br></div><div>But as Arthur noted, this d=
efinition would exempt an entire category of objects like `std::list`, wher=
e move does not leave them in a "trivial" state. The P1144 defini=
tion of relocation is that "move+destroy" is equivalent to "=
memcpy+drop". That's not the same thing as declaring that movement=
leaves the object in a "trivial state".<br></div><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><d=
iv>About the second point.=C2=A0</div><div>We <i>could </i>imagine a way to=
hint the compiler that <font face=3D"courier new,monospace">vector<uniq=
ue_ptr<int>> v(1000000);</font><font face=3D"arial,sans-serif"> co=
uld be </font>both <font face=3D"arial,sans-serif">destroyed and copied (no=
t just moved) around like trivial type (until assigned or might-be-assigned=
).</font></div><div><font face=3D"arial,sans-serif">We could imagine a clea=
red() vector or string, or released() smart pointer to be treated as trivia=
l type. Is the optimizer smart enough? I don't know.=C2=A0</font></div>=
<div><font face=3D"courier new,monospace"></font><font face=3D"arial,sans-s=
erif"></font><br></div><div><span style=3D"display:inline!important;float:n=
one;background-color:transparent;color:rgb(34,34,34);font-family:"Aria=
l","Helvetica",sans-serif;font-size:13px;font-style:normal;f=
ont-variant:normal;font-weight:400;letter-spacing:normal;text-align:left;te=
xt-decoration:none;text-indent:0px;text-transform:none;white-space:normal;w=
ord-spacing:0px">To be clear, these are non-proposal observations.</span></=
div><div>=C2=A0</div><div>Thanks.</div><div><br></div><div>* Should this wo=
rk with an object with no move ctor? Does not feel right, TBH, but will not=
argue over that.</div><div><br></div><br>On Monday, July 23, 2018 at 8:10:=
11 AM UTC+3, Arthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr">On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, <a>mihail=
n...@gmail.com</a> 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>Hello, I am reading <a href=3D"https://quuxplusone.github.io/=
blog/code/object-relocation-in-terms-of-move-plus-destroy-draft-7.html" rel=
=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www=
..google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fob=
ject-relocation-in-terms-of-move-plus-destroy-draft-7.html\x26sa\x3dD\x26sn=
tz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg';return true;" onc=
lick=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquux=
plusone.github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-move-plus-d=
estroy-draft-7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8=
x1hnYAquNdXWg';return true;">D1144R0</a> and <a href=3D"http://www.open=
-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf" rel=3D"nofollow" targ=
et=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.com/url?q\x=
3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018=
%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj6h9=
NquGMikA';return true;" onclick=3D"this.href=3D'http://www.google.c=
om/url?q\x3dhttp%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpap=
ers%2F2018%2Fp1029r0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXI=
EvDs0sj6h9NquGMikA';return true;">p1029r0</a></div><div><br></div><div>=
First that comes to my attention is the fact that the term 'relocation&=
#39; means different things in both proposals.</div><div>This is of no surp=
rise considering the word 'relocation' is more or less a synonym of=
'move'.=C2=A0</div></div></blockquote><div><br></div><div>Basicall=
y agreed (although I also agree with Nicol that <i>naming</i> is less impor=
tant than <i>doing</i>). =C2=A0Some of the references in P1144 talk about n=
aming; you'll notice that both Qt and BSL actually call the operation b=
y the name "move", because they pre-date C++11 "move semanti=
cs." (And <a href=3D"https://quuxplusone.github.io/blog/code/object-re=
location-in-terms-of-move-plus-destroy-draft-7.html#biblio-n1377" rel=3D"no=
follow" target=3D"_blank" onmousedown=3D"this.href=3D'https://www.googl=
e.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-r=
elocation-in-terms-of-move-plus-destroy-draft-7.html%23biblio-n1377\x26sa\x=
3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGGDmj3MZCPccNDQDN1yZMpM6N1kw';return t=
rue;" onclick=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%=
2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-mo=
ve-plus-destroy-draft-7.html%23biblio-n1377\x26sa\x3dD\x26sntz\x3d1\x26usg\=
x3dAFQjCNGGDmj3MZCPccNDQDN1yZMpM6N1kw';return true;">N1377</a> indicate=
s that C++0x really badly=C2=A0<i>wanted</i> to have destructive-move seman=
tics; the "construct, steal guts, but don't destroy" semantic=
s that we actually got in C++11 were a bit of a compromise, based on the fa=
ct that they were actually implementable.) =C2=A0And in other languages wit=
hout C++11's baggage, such as <a href=3D"https://github.com/apple/swift=
/blob/master/docs/ABIStabilityManifesto.md#layout-and-properties-of-types" =
rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'https://=
www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fapple%2Fswift%2Fblob%2Fm=
aster%2Fdocs%2FABIStabilityManifesto.md%23layout-and-properties-of-types\x2=
6sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFtZK5MnJ1twYNFbXEhBzAyJvBJ5Q';ret=
urn true;" onclick=3D"this.href=3D'https://www.google.com/url?q\x3dhttp=
s%3A%2F%2Fgithub.com%2Fapple%2Fswift%2Fblob%2Fmaster%2Fdocs%2FABIStabilityM=
anifesto.md%23layout-and-properties-of-types\x26sa\x3dD\x26sntz\x3d1\x26usg=
\x3dAFQjCNFtZK5MnJ1twYNFbXEhBzAyJvBJ5Q';return true;">Swift</a>, they a=
ctually have no problem using the word "move" for destructive-mov=
e!</div><div><br></div><div>But in C++, we definitely can't use the wor=
d "move"; it's occupied. So P1144 uses the name "relocat=
e", just like EASTL and Folly.</div><div><br></div><div><br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div></div><blockquote=
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;padding-left:1ex;b=
order-left-color:rgb(204,204,204);border-left-width:1px;border-left-style:s=
olid">Interestingly this is more true in C++ then human language as move in=
C++ already means "establish yourself in a new place", where in =
human language this might not be the case.</blockquote><div><br></div><div>=
If a concepts can mean different things, and is actually named with a synon=
ym of other, there seems to be a problem there.</div><div><br></div><div>Ar=
guably 1144 does a better job of creating "real" new category - m=
ove+destroy - but this category end up superficial and is introduced only s=
o that a "trivial" version of it can be introduced - move+don'=
;t_destroy.</div></div></blockquote><div><br></div><div>To be pedantically =
clear: You're using "move" here in its English sense, not its=
C++ sense. =C2=A0Relocate means "move in the C++ sense,=C2=A0<i>plus<=
/i> destroy"; or, if trivial, then the implementation is permitted to =
"<i>neither</i> move in the C++ sense, <i>nor</i> destroy." =C2=
=A0The total number of [move-]constructions and destructions must always re=
main balanced.</div><div><br></div><div><br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"ltr"><div>On the other hand, 1029 names relocate=
just a special form of move.</div><div><br></div><div>No matter which one =
is "right", and I don't believe there is "right" he=
re, the point is, 'relocate' is not a good category in general:</di=
v><ul><li>It is <i>not</i> self-explanatory like=C2=A0"move," &qu=
ot;copy," "destroy," and "swap" -=C2=A0 all this a=
re evident to even a non-programmer.</li><li>It is expressed as a sub-categ=
ory of move and not a new, separate category.</li></ul></div></blockquote><=
div>I sympathize with your desire for words to mean what they mean in Engli=
sh, but I think that ship sailed with C++11.</div><div>The meaning of "=
;move" in C++ is <i>not</i> evident to a non-programmer. To the extent=
that the non-programmer thinks they know what it means, they probably imag=
ine something like "relocate." However, we should also remember t=
hat "move" and "copy" are not technically=C2=A0<i>verbs=
</i> in C++ =E2=80=94 they are <i>adverbs</i>. =C2=A0We do not "copy&q=
uot; objects in C++; we "copy-construct" them or "copy-assig=
n" them. =C2=A0We do not "move" objects; we "move-const=
ruct" them or "move-assign" them.</div><div>However, we do &=
quot;swap" objects, and we do "relocate" objects.</div><div>=
We might even handwavily say that C++03 programs "copy-swap" obje=
cts whereas C++11 programs "move-swap" them. =C2=A0C++11's `s=
td::swap` relies on the assumption that "copy-swap" and "mov=
e-swap" ought to have the same observable effects.</div><div><br></div=
><div><br></div><div><br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div=
dir=3D"ltr"><div>What other thing that comes to my attention is that in ac=
tuality, there is no new category, but instead a restoration of triviality.=
=C2=A0</div><div>This is, we can see that some (many, many) objects <i>beco=
me</i> trivial when moved - after we move a unique_ptr, its destructor can =
be trivial. [...]</div></div></blockquote><div><br></div><div>(Pedantically=
: this is not the C++ definition of "trivial." I prefer to say &q=
uot;no-op." But I see what you mean by the word in this context.)</div=
><div><br></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"><d=
iv>Further, <i>other</i> functions can trivialize the object destruction: [=
....]</div><div><b></b><i></i><u></u><sub></sub><sup></sup><strike></strike>=
<br></div><div><font face=3D"courier new,monospace">pointer unique_ptr::rel=
ease() noexcept=C2=A0</font><span style=3D"font-family:"courier new&qu=
ot;,monospace">[[ensures: trivial_destruction]]</span></div><div><font face=
=3D"courier new,monospace">{</font></div><div><font face=3D"courier new,mon=
ospace">=C2=A0 // implementation</font></div><div><font face=3D"courier new=
,monospace">}</font></div></div></blockquote><div><br></div><div>This is an=
interesting and perhaps fruitful observation. =C2=A0For many trivially rel=
ocatable types, the move constructor ensures that the object is left in a s=
tate where destruction is a no-op.(*)</div><div>P1144 takes this observatio=
n and says, "Let's just skip the no-op destruction, at the library=
level."</div><div>P1029 takes this observation and says, "Let=
9;s give a name to that state =E2=80=94 let's call it the default-const=
ructed state."</div><div>You're saying, "Let's use Contra=
cts to indicate to the compiler when an object is in that state."</div=
><div><br></div><div>I think this is a philosophically sound idea; but I do=
n't see how it would really change anything for compiler-writers compar=
ed to what we have today. I mean, already today we have</div><div><br></div=
><div>=C2=A0 =C2=A0 inline unique_ptr::~unique_ptr() {</div><div>=C2=A0 =C2=
=A0 =C2=A0 =C2=A0 if (m_ptr) delete m_ptr;</div><div>=C2=A0 =C2=A0 }</div><=
div><br></div><div>A sufficiently smart compiler <i>already knows</i> that =
unique_ptr::release() always leaves the object with m_ptr=3D=3Dnullptr, and=
it <i>already knows</i> that if m_ptr=3D=3Dnullptr then the destructor is =
a no-op (because it can see the whole body of the inline destructor). =C2=
=A0Adding a contract like [[ensures: trivial_destruction]] doesn't actu=
ally communicate any <i>new</i> information to the compiler, does it?</div>=
<div><br></div><div>And yet, compilers today <i>are</i> leaving performance=
on the table when it comes to this kind of optimization; and implementing =
P1144 <i>does</i> get that performance back. Suppose we went with something=
like this Contracts idea; what would you expect codegen to look like, and =
what's your explanation for why that codegen doesn't <i>already</i>=
happen?</div><div><br></div><div>=E2=80=93Arthur</div><div><br></div><div>=
(*) =E2=80=94 <i>Some</i> trivially relocatable types, such as a std::list =
whose default-constructed state requires allocation, do=C2=A0<i>not</i>=C2=
=A0have this property. For these types, destructing a moved-from object is =
<i>not</i> a no-op, because it must deallocate the sentinel node. Another e=
xample would be a "shared_ptr" with a copy constructor but no mov=
e constructor. P1144 optimizes these types nicely. I think your approach ex=
plicitly prohibits optimizing them. I don't think P1029 ponders them at=
all, which means in practice it wouldn't optimize them. For the purpos=
es of exploring your Contracts idea, I am okay with saying that we don'=
t need to optimize such types; but in this footnote I want to emphasize tha=
t they do exist and that P1144 handles them well. ;)</div></div></blockquot=
e></div></blockquote></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/67b035da-5306-49c1-8058-5e647a5ff654%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/67b035da-5306-49c1-8058-5e647a5ff654=
%40isocpp.org</a>.<br />
------=_Part_8114_1359204786.1532354210812--
------=_Part_8113_1026738434.1532354210811--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 23 Jul 2018 07:49:33 -0700 (PDT)
Raw View
------=_Part_7968_340680487.1532357373132
Content-Type: multipart/alternative;
boundary="----=_Part_7969_1237617165.1532357373132"
------=_Part_7969_1237617165.1532357373132
Content-Type: text/plain; charset="UTF-8"
On Monday, July 23, 2018 at 9:56:50 AM UTC-4, Nicol Bolas wrote:
>
> On Monday, July 23, 2018 at 6:36:27 AM UTC-4, mihailn...@gmail.com wrote:
>>
>> Hello,
>>
>> The point I was trying to make is that we are focused on a corner of a
>> concept that is much broader.
>>
>> The broader concept is the fact that triviality is a state. Yes, it is
>> per type as far as C++ is concerned, but the objective reality is that it
>> is a state for all objects in std and many, many others.
>> Some objects never leave that state, other do, and very few in the world
>> are never in it.
>>
>
> One problem I see here is the question of what "triviality" means. There
> are many kinds of trivial operations. Some types are trivial; others are
> only trivially copyable. And so forth.
>
> Which trivial operations can be ephemeral in this way? Is there a way to
> test when an object has which trivial operations?
>
> I have a nice function for performing bytewise-copies of objects and
> arrays, which is guarded by `is_trivially_copyable<T>`. That is a good way
> to catch errors. With P1144, I can simply update that to an
> `is_trivially_relocatable<T>`. What you're suggesting would make it
> impossible to have any compile-time guards on the function.
>
> We tap into that observation for the move+destroy/defaulted scenario, but
>> the broader observation holds in other cases as well.
>>
>> The side effects of all this are two
>>
>> First we could describe what are we are doing in terms of notions
>> everybody knows.
>> Second, we could look outside strictly move-destroy, as, on hand, other
>> actions (besides move) bring non-trivial objects in and out of
>> "triviality", and, on the other, not only destroy can take advantage of
>> "triviality", but copy as well
>>
>> About the first point.
>> We *could* for instance name "trivially relocatable" "trivially
>> destructible after move" *, because untimely this is what we tap into. This
>> is clear both for the compiler and the user.
>> This free us from introducing the relocation concept altogether.
>>
>
> But as Arthur noted, this definition would exempt an entire category of
> objects like `std::list`, where move does not leave them in a "trivial"
> state. The P1144 definition of relocation is that "move+destroy" is
> equivalent to "memcpy+drop". That's not the same thing as declaring that
> movement leaves the object in a "trivial state".
>
Also, I realized that the ephemeral triviality notion is missing something
critical. Here's what I mean.
By declaring that "move+destroy" is equivalent to "memcpy+drop", you're
effectively saying that users must treat the source objects after a memcpy
as if they have been destroyed. Treat them as though their lifetime has
already ended, and you must not access them as those objects again (unless
you create a new object in that storage).
Your way would have a type declare that its move constructor (for example)
would conceptually leave the object in a trivially destructible state, and
therefore presumably allow you to perform a `memcpy` on the object. But
where would it say that the source object conceptually *has been destroyed*?
After all, an object that is "trivially destructible" isn't *destroyed*
yet. So does the object still exist? And if it does not, why does putting
it in a "trivially destructible state" destroy it? After all, in normal
code, if you move from a `vector`, you can still manipulate the old one
(with certain interfaces).
That's why it's important that P1144 deals with the twin operations
"move+destroy". It is performing that pair of them in sequence that allows
you to replace that pair with "memcpy+drop". The two operations are linked,
and I don't think this notion of "move causes triviality" will be able to
have the same effect.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/202974c9-8d0d-4f30-a983-94bfbf84b0bb%40isocpp.org.
------=_Part_7969_1237617165.1532357373132
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, July 23, 2018 at 9:56:50 AM UTC-4, Nico=
l Bolas wrote:<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"=
>On Monday, July 23, 2018 at 6:36:27 AM UTC-4, <a>mihailn...@gmail.com</a> =
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>Hello,<=
/div><div><br></div><div>The point I was trying to make is that we are focu=
sed on a corner of a concept that is much broader.</div><div><br></div><div=
>The broader concept is the fact that triviality is a state. Yes, it is per=
type as far as C++ is concerned, but the objective reality is that it is a=
state for all objects in std and many, many others.=C2=A0</div><div>Some o=
bjects never leave that state, other do, and very few in the world are neve=
r in it.</div></div></blockquote><div><br></div><div>One problem I see here=
is the question of what "triviality" means. There are many kinds=
of trivial operations. Some types are trivial; others are only trivially c=
opyable. And so forth.</div><div><br></div><div>Which trivial operations ca=
n be ephemeral in this way? Is there a way to test when an object has which=
trivial operations?</div><div><br></div><div>I have a nice function for pe=
rforming bytewise-copies of objects and arrays, which is guarded by `is_tri=
vially_copyable<T>`. That is a good way to catch errors. With P1144, =
I can simply update that to an `is_trivially_relocatable<T>`. What yo=
u're suggesting would make it impossible to have any compile-time guard=
s on the function.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div></div><div>We tap into that observation for the m=
ove+destroy/defaulted scenario, but the broader observation holds in other =
cases as well.</div><div><br></div><div>The side effects of all this are tw=
o</div><div><br></div><div>First we could describe what are we are doing in=
terms of notions everybody knows.</div><div>Second, we could look outside =
strictly move-destroy, as, on hand, other actions (besides move) bring non-=
trivial objects in and out of "triviality", and, on the other, no=
t only destroy can take advantage of "triviality", but copy as we=
ll</div><div><br></div><div>About the first point.=C2=A0</div><div>We <i>co=
uld</i> for instance name "trivially relocatable" "trivially=
destructible after move" *, because untimely this is what we tap into=
.. This is clear both for the compiler and the user.=C2=A0</div><div>This fr=
ee us from introducing the relocation concept altogether.</div></div></bloc=
kquote><div><br></div><div>But as Arthur noted, this definition would exemp=
t an entire category of objects like `std::list`, where move does not leave=
them in a "trivial" state. The P1144 definition of relocation is=
that "move+destroy" is equivalent to "memcpy+drop". Th=
at's not the same thing as declaring that movement leaves the object in=
a "trivial state".<br></div></div></blockquote><div><br></div><d=
iv>Also, I realized that the ephemeral triviality notion is missing somethi=
ng critical. Here's what I mean.</div><div><br></div><div>By declaring =
that "move+destroy" is equivalent to "memcpy+drop", you=
're effectively saying that users must treat the source objects after a=
memcpy as if they have been destroyed. Treat them as though their lifetime=
has already ended, and you must not access them as those objects again (un=
less you create a new object in that storage).</div><div><br></div><div>You=
r way would have a type declare that its move constructor (for example) wou=
ld conceptually leave the object in a trivially destructible state, and the=
refore presumably allow you to perform a `memcpy` on the object. But where =
would it say that the source object conceptually <i>has been destroyed</i>?=
After all, an object that is "trivially destructible" isn't =
<i>destroyed</i> yet. So does the object still exist? And if it does not, w=
hy does putting it in a "trivially destructible state" destroy it=
? After all, in normal code, if you move from a `vector`, you can still man=
ipulate the old one (with certain interfaces).<br></div><div><br></div><div=
>That's why it's important that P1144 deals with the twin operation=
s "move+destroy". It is performing that pair of them in sequence =
that allows you to replace that pair with "memcpy+drop". The two =
operations are linked, and I don't think this notion of "move caus=
es triviality" will be able to have the same effect.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/202974c9-8d0d-4f30-a983-94bfbf84b0bb%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/202974c9-8d0d-4f30-a983-94bfbf84b0bb=
%40isocpp.org</a>.<br />
------=_Part_7969_1237617165.1532357373132--
------=_Part_7968_340680487.1532357373132--
.
Author: mihailnajdenov@gmail.com
Date: Mon, 23 Jul 2018 12:00:55 -0700 (PDT)
Raw View
------=_Part_8576_1751907610.1532372455807
Content-Type: multipart/alternative;
boundary="----=_Part_8577_641221187.1532372455808"
------=_Part_8577_641221187.1532372455808
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>
> On Monday, July 23, 2018 at 6:36:27 AM UTC-4, mihailn...@gmail.com wrote:
>>
>> Hello,
>>
>> The point I was trying to make is that we are focused on a corner of a=
=20
>> concept that is much broader.
>>
>> The broader concept is the fact that triviality is a state. Yes, it is=
=20
>> per type as far as C++ is concerned, but the objective reality is that i=
t=20
>> is a state for all objects in std and many, many others.=20
>> Some objects never leave that state, other do, and very few in the world=
=20
>> are never in it.
>>
>
> One problem I see here is the question of what "triviality" means. There=
=20
> are many kinds of trivial operations. Some types are trivial; others are=
=20
> only trivially copyable. And so forth.
>
> Which trivial operations can be ephemeral in this way? Is there a way to=
=20
> test when an object has which trivial operations?
>
> I have a nice function for performing bytewise-copies of objects and=20
> arrays, which is guarded by `is_trivially_copyable<T>`. That is a good wa=
y=20
> to catch errors. With P1144, I can simply update that to an=20
> `is_trivially_relocatable<T>`. What you're suggesting would make it=20
> impossible to have any compile-time guards on the function.
>
> We tap into that observation for the move+destroy/defaulted scenario, but=
=20
>> the broader observation holds in other cases as well.
>>
>> The side effects of all this are two
>>
>> First we could describe what are we are doing in terms of notions=20
>> everybody knows.
>> Second, we could look outside strictly move-destroy, as, on hand, other=
=20
>> actions (besides move) bring non-trivial objects in and out of=20
>> "triviality", and, on the other, not only destroy can take advantage of=
=20
>> "triviality", but copy as well
>>
>> About the first point.=20
>> We *could* for instance name "trivially relocatable" "trivially=20
>> destructible after move" *, because untimely this is what we tap into. T=
his=20
>> is clear both for the compiler and the user.=20
>> This free us from introducing the relocation concept altogether.
>>
>
> =20
> But as Arthur noted, this definition would exempt an entire category of=
=20
> objects like `std::list`, where move does not leave them in a "trivial"=
=20
> state. The P1144 definition of relocation is that "move+destroy" is=20
> equivalent to "memcpy+drop". That's not the same thing as declaring that=
=20
> movement leaves the object in a "trivial state".
>
=20
I see, so 1144 "works" even if after 'move', the object needs to be=20
non-trivially destroyed. Yeah, my observations do not apply then.
I can't say I am crazy about this, though. I was happy to see destructing=
=20
move go and a simple idea, like telling the compiler the cases he can=20
optimize, come in its place.
But this is this + way to cheat/sidestep normal object lifetime.=20
And cheating is needed just for that 0.1% of all cases!=20
99% of the objects can have their moves optimized by memcopy + noop=20
destruct and *still* be completely as-if move + destructor were called (no=
=20
observable difference).=20
The requirements when to optimize would also be nowhere near as strict as=
=20
normal c++ rules are still apply.=20
=20
Anyways, I think the paper should be more specific about these cases, give=
=20
examples, make it clear this relocation thing is actually *not* just=20
"optimized move+destroy" as there *can* be observable difference.
About the second point.=20
>> We *could *imagine a way to hint the compiler that vector<unique_ptr<int=
>>=20
>> v(1000000); could be both destroyed and copied (not just moved) around=
=20
>> like trivial type (until assigned or might-be-assigned).
>> We could imagine a cleared() vector or string, or released() smart=20
>> pointer to be treated as trivial type. Is the optimizer smart enough? I=
=20
>> don't know.=20
>>
>> To be clear, these are non-proposal observations.
>> =20
>> Thanks.
>>
>> * Should this work with an object with no move ctor? Does not feel right=
,=20
>> TBH, but will not argue over that.
>>
>>
>> On Monday, July 23, 2018 at 8:10:11 AM UTC+3, Arthur O'Dwyer wrote:
>>>
>>> On Sunday, July 22, 2018 at 3:01:31 AM UTC-7, mihailn...@gmail.com=20
>>> wrote:
>>>>
>>>> Hello, I am reading D1144R0=20
>>>> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of=
-move-plus-destroy-draft-7.html>=20
>>>> and p1029r0=20
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1029r0.pdf>
>>>>
>>>> First that comes to my attention is the fact that the term 'relocation=
'=20
>>>> means different things in both proposals.
>>>> This is of no surprise considering the word 'relocation' is more or=20
>>>> less a synonym of 'move'.=20
>>>>
>>>
>>> Basically agreed (although I also agree with Nicol that *naming* is=20
>>> less important than *doing*). Some of the references in P1144 talk=20
>>> about naming; you'll notice that both Qt and BSL actually call the=20
>>> operation by the name "move", because they pre-date C++11 "move semanti=
cs."=20
>>> (And N1377=20
>>> <https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-=
move-plus-destroy-draft-7.html#biblio-n1377>=20
>>> indicates that C++0x really badly *wanted* to have destructive-move=20
>>> semantics; the "construct, steal guts, but don't destroy" semantics tha=
t we=20
>>> actually got in C++11 were a bit of a compromise, based on the fact tha=
t=20
>>> they were actually implementable.) And in other languages without C++1=
1's=20
>>> baggage, such as Swift=20
>>> <https://github.com/apple/swift/blob/master/docs/ABIStabilityManifesto.=
md#layout-and-properties-of-types>,=20
>>> they actually have no problem using the word "move" for destructive-mov=
e!
>>>
>>> But in C++, we definitely can't use the word "move"; it's occupied. So=
=20
>>> P1144 uses the name "relocate", just like EASTL and Folly.
>>>
>>>
>>> Interestingly this is more true in C++ then human language as move in=
=20
>>>>> C++ already means "establish yourself in a new place", where in human=
=20
>>>>> language this might not be the case.
>>>>
>>>>
>>>> If a concepts can mean different things, and is actually named with a=
=20
>>>> synonym of other, there seems to be a problem there.
>>>>
>>>> Arguably 1144 does a better job of creating "real" new category -=20
>>>> move+destroy - but this category end up superficial and is introduced =
only=20
>>>> so that a "trivial" version of it can be introduced - move+don't_destr=
oy.
>>>>
>>>
>>> To be pedantically clear: You're using "move" here in its English sense=
,=20
>>> not its C++ sense. Relocate means "move in the C++ sense, *plus*=20
>>> destroy"; or, if trivial, then the implementation is permitted to "
>>> *neither* move in the C++ sense, *nor* destroy." The total number of=
=20
>>> [move-]constructions and destructions must always remain balanced.
>>>
>>>
>>> On the other hand, 1029 names relocate just a special form of move.
>>>>
>>>> No matter which one is "right", and I don't believe there is "right"=
=20
>>>> here, the point is, 'relocate' is not a good category in general:
>>>>
>>>> - It is *not* self-explanatory like "move," "copy," "destroy," and=
=20
>>>> "swap" - all this are evident to even a non-programmer.
>>>> - It is expressed as a sub-category of move and not a new, separate=
=20
>>>> category.
>>>>
>>>> I sympathize with your desire for words to mean what they mean in=20
>>> English, but I think that ship sailed with C++11.
>>> The meaning of "move" in C++ is *not* evident to a non-programmer. To=
=20
>>> the extent that the non-programmer thinks they know what it means, they=
=20
>>> probably imagine something like "relocate." However, we should also=20
>>> remember that "move" and "copy" are not technically *verbs* in C++ =E2=
=80=94=20
>>> they are *adverbs*. We do not "copy" objects in C++; we=20
>>> "copy-construct" them or "copy-assign" them. We do not "move" objects;=
we=20
>>> "move-construct" them or "move-assign" them.
>>> However, we do "swap" objects, and we do "relocate" objects.
>>> We might even handwavily say that C++03 programs "copy-swap" objects=20
>>> whereas C++11 programs "move-swap" them. C++11's `std::swap` relies on=
the=20
>>> assumption that "copy-swap" and "move-swap" ought to have the same=20
>>> observable effects.
>>>
>>>
>>>
>>> What other thing that comes to my attention is that in actuality, there=
=20
>>>> is no new category, but instead a restoration of triviality.=20
>>>> This is, we can see that some (many, many) objects *become* trivial=20
>>>> when moved - after we move a unique_ptr, its destructor can be trivial=
..=20
>>>> [...]
>>>>
>>>
>>> (Pedantically: this is not the C++ definition of "trivial." I prefer to=
=20
>>> say "no-op." But I see what you mean by the word in this context.)
>>>
>>> Further, *other* functions can trivialize the object destruction: [...]
>>>>
>>>> pointer unique_ptr::release() noexcept [[ensures: trivial_destruction]=
]
>>>> {
>>>> // implementation
>>>> }
>>>>
>>>
>>> This is an interesting and perhaps fruitful observation. For many=20
>>> trivially relocatable types, the move constructor ensures that the obje=
ct=20
>>> is left in a state where destruction is a no-op.(*)
>>> P1144 takes this observation and says, "Let's just skip the no-op=20
>>> destruction, at the library level."
>>> P1029 takes this observation and says, "Let's give a name to that state=
=20
>>> =E2=80=94 let's call it the default-constructed state."
>>> You're saying, "Let's use Contracts to indicate to the compiler when an=
=20
>>> object is in that state."
>>>
>>> I think this is a philosophically sound idea; but I don't see how it=20
>>> would really change anything for compiler-writers compared to what we h=
ave=20
>>> today. I mean, already today we have
>>>
>>> inline unique_ptr::~unique_ptr() {
>>> if (m_ptr) delete m_ptr;
>>> }
>>>
>>> A sufficiently smart compiler *already knows* that=20
>>> unique_ptr::release() always leaves the object with m_ptr=3D=3Dnullptr,=
and it *already=20
>>> knows* that if m_ptr=3D=3Dnullptr then the destructor is a no-op (becau=
se=20
>>> it can see the whole body of the inline destructor). Adding a contract=
=20
>>> like [[ensures: trivial_destruction]] doesn't actually communicate any=
=20
>>> *new* information to the compiler, does it?
>>>
>>> And yet, compilers today *are* leaving performance on the table when it=
=20
>>> comes to this kind of optimization; and implementing P1144 *does* get=
=20
>>> that performance back. Suppose we went with something like this Contrac=
ts=20
>>> idea; what would you expect codegen to look like, and what's your=20
>>> explanation for why that codegen doesn't *already* happen?
>>>
>>> =E2=80=93Arthur
>>>
>>> (*) =E2=80=94 *Some* trivially relocatable types, such as a std::list w=
hose=20
>>> default-constructed state requires allocation, do *not* have this=20
>>> property. For these types, destructing a moved-from object is *not* a=
=20
>>> no-op, because it must deallocate the sentinel node. Another example wo=
uld=20
>>> be a "shared_ptr" with a copy constructor but no move constructor. P114=
4=20
>>> optimizes these types nicely. I think your approach explicitly prohibit=
s=20
>>> optimizing them. I don't think P1029 ponders them at all, which means i=
n=20
>>> practice it wouldn't optimize them. For the purposes of exploring your=
=20
>>> Contracts idea, I am okay with saying that we don't need to optimize su=
ch=20
>>> types; but in this footnote I want to emphasize that they do exist and =
that=20
>>> P1144 handles them well. ;)
>>>
>>
--=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/f24b939b-86c1-4152-a339-d30f8f525f0e%40isocpp.or=
g.
------=_Part_8577_641221187.1532372455808
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nico=
l Bolas wrote:<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"=
>On Monday, July 23, 2018 at 6:36:27 AM UTC-4, <a>mihailn...@gmail.com</a> =
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>Hello,<=
/div><div><br></div><div>The point I was trying to make is that we are focu=
sed on a corner of a concept that is much broader.</div><div><br></div><div=
>The broader concept is the fact that triviality is a state. Yes, it is per=
type as far as C++ is concerned, but the objective reality is that it is a=
state for all objects in std and many, many others.=C2=A0</div><div>Some o=
bjects never leave that state, other do, and very few in the world are neve=
r in it.</div></div></blockquote><div><br></div><div>One problem I see here=
is the question of what "triviality" means. There are many kinds=
of trivial operations. Some types are trivial; others are only trivially c=
opyable. And so forth.</div><div><br></div><div>Which trivial operations ca=
n be ephemeral in this way? Is there a way to test when an object has which=
trivial operations?</div><div><br></div><div>I have a nice function for pe=
rforming bytewise-copies of objects and arrays, which is guarded by `is_tri=
vially_copyable<T>`. That is a good way to catch errors. With P1144, =
I can simply update that to an `is_trivially_relocatable<T>`. What yo=
u're suggesting would make it impossible to have any compile-time guard=
s on the function.</div><div><br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div></div><div>We tap into that observation for the m=
ove+destroy/defaulted scenario, but the broader observation holds in other =
cases as well.</div><div><br></div><div>The side effects of all this are tw=
o</div><div><br></div><div>First we could describe what are we are doing in=
terms of notions everybody knows.</div><div>Second, we could look outside =
strictly move-destroy, as, on hand, other actions (besides move) bring non-=
trivial objects in and out of "triviality", and, on the other, no=
t only destroy can take advantage of "triviality", but copy as we=
ll</div><div><br></div><div>About the first point.=C2=A0</div><div>We <i>co=
uld</i> for instance name "trivially relocatable" "trivially=
destructible after move" *, because untimely this is what we tap into=
.. This is clear both for the compiler and the user.=C2=A0</div><div>This fr=
ee us from introducing the relocation concept altogether.</div></div></bloc=
kquote><div><br></div></div></blockquote><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div></div><div>But as Arthur =
noted, this definition would exempt an entire category of objects like `std=
::list`, where move does not leave them in a "trivial" state. The=
P1144 definition of relocation is that "move+destroy" is equival=
ent to "memcpy+drop". That's not the same thing as declaring =
that movement leaves the object in a "trivial state".<br></div></=
div></blockquote><div>=C2=A0</div><div>I see, so 1144 "works" eve=
n if after 'move', the object needs to be non-trivially destroyed. =
Yeah, my observations do not apply then.</div><div><br></div><div>I can'=
;t say I am crazy about this, though. I was happy to see destructing move g=
o and a simple idea, like telling the compiler the cases he can optimize, c=
ome in its place.</div><div>But this is this + way to cheat/sidestep normal=
object lifetime.=C2=A0</div><div>And cheating is needed just for that 0.1%=
of all cases!=C2=A0</div><div>99% of the objects can have their moves opti=
mized by memcopy + noop destruct and <i>still</i> be completely as-if move =
+ destructor were called (no observable difference).=C2=A0</div><div>The re=
quirements when to optimize would also be nowhere near as strict as normal =
c++ rules are still apply.=C2=A0</div><div>=C2=A0</div><div>Anyways, I thin=
k the paper should be more specific about these cases, give examples, make =
it clear this relocation thing is actually <i>not</i> just "optimized =
move+destroy" as there <i>can</i> be observable difference.</div><div>=
<br></div><div><br></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><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><div>About the second point.=C2=A0</div><div>We <i>could </=
i>imagine a way to hint the compiler that <font face=3D"courier new,monospa=
ce">vector<unique_ptr<int>> v(1000000);</font><font face=3D"ari=
al,sans-serif"> could be </font>both <font face=3D"arial,sans-serif">destro=
yed and copied (not just moved) around like trivial type (until assigned or=
might-be-assigned).</font></div><div><font face=3D"arial,sans-serif">We co=
uld imagine a cleared() vector or string, or released() smart pointer to be=
treated as trivial type. Is the optimizer smart enough? I don't know.=
=C2=A0</font></div><div><font face=3D"courier new,monospace"></font><font f=
ace=3D"arial,sans-serif"></font><br></div><div><span style=3D"display:inlin=
e!important;float:none;background-color:transparent;color:rgb(34,34,34);fon=
t-family:"Arial","Helvetica",sans-serif;font-size:13px;=
font-style:normal;font-variant:normal;font-weight:400;letter-spacing:normal=
;text-align:left;text-decoration:none;text-indent:0px;text-transform:none;w=
hite-space:normal;word-spacing:0px">To be clear, these are non-proposal obs=
ervations.</span></div><div>=C2=A0</div><div>Thanks.</div><div><br></div><d=
iv>* Should this work with an object with no move ctor? Does not feel right=
, TBH, but will not argue over that.</div><div><br></div><br>On Monday, Jul=
y 23, 2018 at 8:10:11 AM UTC+3, Arthur O'Dwyer wrote:<blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">On Sunday, July 22, 2018 at 3:01:31=
AM UTC-7, <a>mihailn...@gmail.com</a> wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><div>Hello, I am reading <a onmousedown=3D"this.=
href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.githu=
b.io%2Fblog%2Fcode%2Fobject-relocation-in-terms-of-move-plus-destroy-draft-=
7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg=
';return true;" onclick=3D"this.href=3D'https://www.google.com/url?=
q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-relocation-=
in-terms-of-move-plus-destroy-draft-7.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x=
3dAFQjCNG93lHK8KDaaxON8x1hnYAquNdXWg';return true;" href=3D"https://quu=
xplusone.github.io/blog/code/object-relocation-in-terms-of-move-plus-destro=
y-draft-7.html" target=3D"_blank" rel=3D"nofollow">D1144R0</a> and <a onmou=
sedown=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.=
open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp1029r0.pdf\x26s=
a\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj6h9NquGMikA';retur=
n true;" onclick=3D"this.href=3D'http://www.google.com/url?q\x3dhttp%3A=
%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2018%2Fp1029r=
0.pdf\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGBQgX7XCXIEvDs0sj6h9NquGMikA&=
#39;;return true;" href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/pape=
rs/2018/p1029r0.pdf" target=3D"_blank" rel=3D"nofollow">p1029r0</a></div><d=
iv><br></div><div>First that comes to my attention is the fact that the ter=
m 'relocation' means different things in both proposals.</div><div>=
This is of no surprise considering the word 'relocation' is more or=
less a synonym of 'move'.=C2=A0</div></div></blockquote><div><br><=
/div><div>Basically agreed (although I also agree with Nicol that <i>naming=
</i> is less important than <i>doing</i>). =C2=A0Some of the references in =
P1144 talk about naming; you'll notice that both Qt and BSL actually ca=
ll the operation by the name "move", because they pre-date C++11 =
"move semantics." (And <a onmousedown=3D"this.href=3D'https:/=
/www.google.com/url?q\x3dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%=
2Fobject-relocation-in-terms-of-move-plus-destroy-draft-7.html%23biblio-n13=
77\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNGGDmj3MZCPccNDQDN1yZMpM6N1kw'=
;;return true;" onclick=3D"this.href=3D'https://www.google.com/url?q\x3=
dhttps%3A%2F%2Fquuxplusone.github.io%2Fblog%2Fcode%2Fobject-relocation-in-t=
erms-of-move-plus-destroy-draft-7.html%23biblio-n1377\x26sa\x3dD\x26sntz\x3=
d1\x26usg\x3dAFQjCNGGDmj3MZCPccNDQDN1yZMpM6N1kw';return true;" href=3D"=
https://quuxplusone.github.io/blog/code/object-relocation-in-terms-of-move-=
plus-destroy-draft-7.html#biblio-n1377" target=3D"_blank" rel=3D"nofollow">=
N1377</a> indicates that C++0x really badly=C2=A0<i>wanted</i> to have dest=
ructive-move semantics; the "construct, steal guts, but don't dest=
roy" semantics that we actually got in C++11 were a bit of a compromis=
e, based on the fact that they were actually implementable.) =C2=A0And in o=
ther languages without C++11's baggage, such as <a onmousedown=3D"this.=
href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fappl=
e%2Fswift%2Fblob%2Fmaster%2Fdocs%2FABIStabilityManifesto.md%23layout-and-pr=
operties-of-types\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFtZK5MnJ1twYNFbXE=
hBzAyJvBJ5Q';return true;" onclick=3D"this.href=3D'https://www.goog=
le.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fapple%2Fswift%2Fblob%2Fmaster%2F=
docs%2FABIStabilityManifesto.md%23layout-and-properties-of-types\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNFtZK5MnJ1twYNFbXEhBzAyJvBJ5Q';return true=
;" href=3D"https://github.com/apple/swift/blob/master/docs/ABIStabilityMani=
festo.md#layout-and-properties-of-types" target=3D"_blank" rel=3D"nofollow"=
>Swift</a>, they actually have no problem using the word "move" f=
or destructive-move!</div><div><br></div><div>But in C++, we definitely can=
't use the word "move"; it's occupied. So P1144 uses the =
name "relocate", just like EASTL and Folly.</div><div><br></div><=
div><br></div><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=
></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;=
padding-left:1ex;border-left-color:rgb(204,204,204);border-left-width:1px;b=
order-left-style:solid">Interestingly this is more true in C++ then human l=
anguage as move in C++ already means "establish yourself in a new plac=
e", where in human language this might not be the case.</blockquote><d=
iv><br></div><div>If a concepts can mean different things, and is actually =
named with a synonym of other, there seems to be a problem there.</div><div=
><br></div><div>Arguably 1144 does a better job of creating "real"=
; new category - move+destroy - but this category end up superficial and is=
introduced only so that a "trivial" version of it can be introdu=
ced - move+don't_destroy.</div></div></blockquote><div><br></div><div>T=
o be pedantically clear: You're using "move" here in its Engl=
ish sense, not its C++ sense. =C2=A0Relocate means "move in the C++ se=
nse,=C2=A0<i>plus</i> destroy"; or, if trivial, then the implementatio=
n is permitted to "<i>neither</i> move in the C++ sense, <i>nor</i> de=
stroy." =C2=A0The total number of [move-]constructions and destruction=
s must always remain balanced.</div><div><br></div><div><br></div><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>On the other hand, 102=
9 names relocate just a special form of move.</div><div><br></div><div>No m=
atter which one is "right", and I don't believe there is &quo=
t;right" here, the point is, 'relocate' is not a good category=
in general:</div><ul><li>It is <i>not</i> self-explanatory like=C2=A0"=
;move," "copy," "destroy," and "swap" -=
=C2=A0 all this are evident to even a non-programmer.</li><li>It is express=
ed as a sub-category of move and not a new, separate category.</li></ul></d=
iv></blockquote><div>I sympathize with your desire for words to mean what t=
hey mean in English, but I think that ship sailed with C++11.</div><div>The=
meaning of "move" in C++ is <i>not</i> evident to a non-programm=
er. To the extent that the non-programmer thinks they know what it means, t=
hey probably imagine something like "relocate." However, we shoul=
d also remember that "move" and "copy" are not technica=
lly=C2=A0<i>verbs</i> in C++ =E2=80=94 they are <i>adverbs</i>. =C2=A0We do=
not "copy" objects in C++; we "copy-construct" them or=
"copy-assign" them. =C2=A0We do not "move" objects; we=
"move-construct" them or "move-assign" them.</div><div=
>However, we do "swap" objects, and we do "relocate" ob=
jects.</div><div>We might even handwavily say that C++03 programs "cop=
y-swap" objects whereas C++11 programs "move-swap" them. =C2=
=A0C++11's `std::swap` relies on the assumption that "copy-swap&qu=
ot; and "move-swap" ought to have the same observable effects.</d=
iv><div><br></div><div><br></div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div>What other thing that comes to my attent=
ion is that in actuality, there is no new category, but instead a restorati=
on of triviality.=C2=A0</div><div>This is, we can see that some (many, many=
) objects <i>become</i> trivial when moved - after we move a unique_ptr, it=
s destructor can be trivial. [...]</div></div></blockquote><div><br></div><=
div>(Pedantically: this is not the C++ definition of "trivial." I=
prefer to say "no-op." But I see what you mean by the word in th=
is context.)</div><div><br></div><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>Further, <i>other</i> functions can trivialize the obje=
ct destruction: [...]</div><div><b></b><i></i><u></u><sub></sub><sup></sup>=
<strike></strike><br></div><div><font face=3D"courier new,monospace">pointe=
r unique_ptr::release() noexcept=C2=A0</font><span style=3D"font-family:&qu=
ot;courier new",monospace">[[ensures: trivial_destruction]]</span></di=
v><div><font face=3D"courier new,monospace">{</font></div><div><font face=
=3D"courier new,monospace">=C2=A0 // implementation</font></div><div><font =
face=3D"courier new,monospace">}</font></div></div></blockquote><div><br></=
div><div>This is an interesting and perhaps fruitful observation. =C2=A0For=
many trivially relocatable types, the move constructor ensures that the ob=
ject is left in a state where destruction is a no-op.(*)</div><div>P1144 ta=
kes this observation and says, "Let's just skip the no-op destruct=
ion, at the library level."</div><div>P1029 takes this observation and=
says, "Let's give a name to that state =E2=80=94 let's call i=
t the default-constructed state."</div><div>You're saying, "L=
et's use Contracts to indicate to the compiler when an object is in tha=
t state."</div><div><br></div><div>I think this is a philosophically s=
ound idea; but I don't see how it would really change anything for comp=
iler-writers compared to what we have today. I mean, already today we have<=
/div><div><br></div><div>=C2=A0 =C2=A0 inline unique_ptr::~unique_ptr() {</=
div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (m_ptr) delete m_ptr;</div><div>=C2=
=A0 =C2=A0 }</div><div><br></div><div>A sufficiently smart compiler <i>alre=
ady knows</i> that unique_ptr::release() always leaves the object with m_pt=
r=3D=3Dnullptr, and it <i>already knows</i> that if m_ptr=3D=3Dnullptr then=
the destructor is a no-op (because it can see the whole body of the inline=
destructor). =C2=A0Adding a contract like [[ensures: trivial_destruction]]=
doesn't actually communicate any <i>new</i> information to the compile=
r, does it?</div><div><br></div><div>And yet, compilers today <i>are</i> le=
aving performance on the table when it comes to this kind of optimization; =
and implementing P1144 <i>does</i> get that performance back. Suppose we we=
nt with something like this Contracts idea; what would you expect codegen t=
o look like, and what's your explanation for why that codegen doesn'=
;t <i>already</i> happen?</div><div><br></div><div>=E2=80=93Arthur</div><di=
v><br></div><div>(*) =E2=80=94 <i>Some</i> trivially relocatable types, suc=
h as a std::list whose default-constructed state requires allocation, do=C2=
=A0<i>not</i>=C2=A0have this property. For these types, destructing a moved=
-from object is <i>not</i> a no-op, because it must deallocate the sentinel=
node. Another example would be a "shared_ptr" with a copy constr=
uctor but no move constructor. P1144 optimizes these types nicely. I think =
your approach explicitly prohibits optimizing them. I don't think P1029=
ponders them at all, which means in practice it wouldn't optimize them=
.. For the purposes of exploring your Contracts idea, I am okay with saying =
that we don't need to optimize such types; but in this footnote I want =
to emphasize that they do exist and that P1144 handles them well. ;)</div><=
/div></blockquote></div></blockquote></div></blockquote></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/f24b939b-86c1-4152-a339-d30f8f525f0e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/f24b939b-86c1-4152-a339-d30f8f525f0e=
%40isocpp.org</a>.<br />
------=_Part_8577_641221187.1532372455808--
------=_Part_8576_1751907610.1532372455807--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 23 Jul 2018 13:06:30 -0700 (PDT)
Raw View
------=_Part_8352_1847914595.1532376390350
Content-Type: multipart/alternative;
boundary="----=_Part_8353_1916003793.1532376390350"
------=_Part_8353_1916003793.1532376390350
Content-Type: text/plain; charset="UTF-8"
On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@gmail.com wrote:
>
> On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>>
>> On Monday, July 23, 2018 at 6:36:27 AM UTC-4, mihailn...@gmail.com wrote:
>>>
>>> Hello,
>>>
>>> The point I was trying to make is that we are focused on a corner of a
>>> concept that is much broader.
>>>
>>> The broader concept is the fact that triviality is a state. Yes, it is
>>> per type as far as C++ is concerned, but the objective reality is that it
>>> is a state for all objects in std and many, many others.
>>> Some objects never leave that state, other do, and very few in the world
>>> are never in it.
>>>
>>
>> One problem I see here is the question of what "triviality" means. There
>> are many kinds of trivial operations. Some types are trivial; others are
>> only trivially copyable. And so forth.
>>
>> Which trivial operations can be ephemeral in this way? Is there a way to
>> test when an object has which trivial operations?
>>
>> I have a nice function for performing bytewise-copies of objects and
>> arrays, which is guarded by `is_trivially_copyable<T>`. That is a good way
>> to catch errors. With P1144, I can simply update that to an
>> `is_trivially_relocatable<T>`. What you're suggesting would make it
>> impossible to have any compile-time guards on the function.
>>
>> We tap into that observation for the move+destroy/defaulted scenario, but
>>> the broader observation holds in other cases as well.
>>>
>>> The side effects of all this are two
>>>
>>> First we could describe what are we are doing in terms of notions
>>> everybody knows.
>>> Second, we could look outside strictly move-destroy, as, on hand, other
>>> actions (besides move) bring non-trivial objects in and out of
>>> "triviality", and, on the other, not only destroy can take advantage of
>>> "triviality", but copy as well
>>>
>>> About the first point.
>>> We *could* for instance name "trivially relocatable" "trivially
>>> destructible after move" *, because untimely this is what we tap into. This
>>> is clear both for the compiler and the user.
>>> This free us from introducing the relocation concept altogether.
>>>
>>
>>
>
>> But as Arthur noted, this definition would exempt an entire category of
>> objects like `std::list`, where move does not leave them in a "trivial"
>> state. The P1144 definition of relocation is that "move+destroy" is
>> equivalent to "memcpy+drop". That's not the same thing as declaring that
>> movement leaves the object in a "trivial state".
>>
>
> I see, so 1144 "works" even if after 'move', the object needs to be
> non-trivially destroyed. Yeah, my observations do not apply then.
>
> I can't say I am crazy about this, though. I was happy to see destructing
> move go and a simple idea, like telling the compiler the cases he can
> optimize, come in its place.
> But this is this + way to cheat/sidestep normal object lifetime.
> And cheating is needed just for that 0.1% of all cases!
> 99% of the objects can have their moves optimized by memcopy + noop
> destruct and *still* be completely as-if move + destructor were called
> (no observable difference).
>
The requirements when to optimize would also be nowhere near as strict as
> normal c++ rules are still apply.
>
> Anyways, I think the paper should be more specific about these cases, give
> examples, make it clear this relocation thing is actually *not* just
> "optimized move+destroy" as there *can* be observable difference.
>
Guaranteed elision has an observable difference from mere copy elision. But
that's the point of the feature.
So too is this. P1144 is not trying to provide a "no observable difference"
guarantee. The point is to be like guaranteed elision: any "observable
differences" are stuff you didn't want to have happen anyway.
But you're right, that it should talk about cases like `std::list`. And I'm
rather surprised that it didn't bring them up.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/388649d9-027b-48e0-a29f-eabc0cd127e4%40isocpp.org.
------=_Part_8353_1916003793.1532376390350
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@g=
mail.com 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=
">On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:<blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr">On Monday, July 23, 2018 at=
6:36:27 AM UTC-4, <a>mihailn...@gmail.com</a> wrote:<blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>Hello,</div><div><br></div><div>The=
point I was trying to make is that we are focused on a corner of a concept=
that is much broader.</div><div><br></div><div>The broader concept is the =
fact that triviality is a state. Yes, it is per type as far as C++ is conce=
rned, but the objective reality is that it is a state for all objects in st=
d and many, many others.=C2=A0</div><div>Some objects never leave that stat=
e, other do, and very few in the world are never in it.</div></div></blockq=
uote><div><br></div><div>One problem I see here is the question of what &qu=
ot;triviality" means. There are many kinds of trivial operations. Some=
types are trivial; others are only trivially copyable. And so forth.</div>=
<div><br></div><div>Which trivial operations can be ephemeral in this way? =
Is there a way to test when an object has which trivial operations?</div><d=
iv><br></div><div>I have a nice function for performing bytewise-copies of =
objects and arrays, which is guarded by `is_trivially_copyable<T>`. T=
hat is a good way to catch errors. With P1144, I can simply update that to =
an `is_trivially_relocatable<T>`. What you're suggesting would ma=
ke it impossible to have any compile-time guards on the function.</div><div=
><br></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><div>We tap into that observation for the move+destroy/defaulted scenar=
io, but the broader observation holds in other cases as well.</div><div><br=
></div><div>The side effects of all this are two</div><div><br></div><div>F=
irst we could describe what are we are doing in terms of notions everybody =
knows.</div><div>Second, we could look outside strictly move-destroy, as, o=
n hand, other actions (besides move) bring non-trivial objects in and out o=
f "triviality", and, on the other, not only destroy can take adva=
ntage of "triviality", but copy as well</div><div><br></div><div>=
About the first point.=C2=A0</div><div>We <i>could</i> for instance name &q=
uot;trivially relocatable" "trivially destructible after move&quo=
t; *, because untimely this is what we tap into. This is clear both for the=
compiler and the user.=C2=A0</div><div>This free us from introducing the r=
elocation concept altogether.</div></div></blockquote><div><br></div></div>=
</blockquote><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr"><div></div><div>But as Arthur noted, this definition would exem=
pt an entire category of objects like `std::list`, where move does not leav=
e them in a "trivial" state. The P1144 definition of relocation i=
s that "move+destroy" is equivalent to "memcpy+drop". T=
hat's not the same thing as declaring that movement leaves the object i=
n a "trivial state".<br></div></div></blockquote><div>=C2=A0</div=
><div>I see, so 1144 "works" even if after 'move', the ob=
ject needs to be non-trivially destroyed. Yeah, my observations do not appl=
y then.</div><div><br></div><div>I can't say I am crazy about this, tho=
ugh. I was happy to see destructing move go and a simple idea, like telling=
the compiler the cases he can optimize, come in its place.</div><div>But t=
his is this + way to cheat/sidestep normal object lifetime.=C2=A0</div><div=
>And cheating is needed just for that 0.1% of all cases!=C2=A0</div><div>99=
% of the objects can have their moves optimized by memcopy + noop destruct =
and <i>still</i> be completely as-if move + destructor were called (no obse=
rvable difference).</div></div></blockquote><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;"><div dir=3D"ltr"><div>The requirements when to optimize would=
also be nowhere near as strict as normal c++ rules are still apply.=C2=A0<=
/div><div>=C2=A0</div><div>Anyways, I think the paper should be more specif=
ic about these cases, give examples, make it clear this relocation thing is=
actually <i>not</i> just "optimized move+destroy" as there <i>ca=
n</i> be observable difference.</div></div></blockquote><div><br></div><div=
>Guaranteed elision has an observable difference from mere copy elision. Bu=
t that's the point of the feature.<br></div><div><br></div><div>So too =
is this. P1144 is not trying to provide a "no observable difference&qu=
ot; guarantee. The point is to be like guaranteed elision: any "observ=
able differences" are stuff you didn't want to have happen anyway.=
<br></div><div><br></div><div>But you're right, that it should talk abo=
ut cases like `std::list`. And I'm rather surprised that it didn't =
bring them up.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/388649d9-027b-48e0-a29f-eabc0cd127e4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/388649d9-027b-48e0-a29f-eabc0cd127e4=
%40isocpp.org</a>.<br />
------=_Part_8353_1916003793.1532376390350--
------=_Part_8352_1847914595.1532376390350--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Mon, 23 Jul 2018 13:57:35 -0700
Raw View
On Sunday, 22 July 2018 22:10:11 PDT Arthur O'Dwyer wrote:
> But in C++, we definitely can't use the word "move"; it's occupied. So
> P1144 uses the name "relocate", just like EASTL and Folly.
Just a side note: "relocation" is already used by the ABI.
extern const char *const strings[] = {
"foo",
"bar",
"baz",
"quux"
};
Creates 4 relocations.
It's relevant for C++ developers because some projects frown upon creating
unnecessary relocations like the above. The above can be implemented with zero
relocations using code generation (example [1]) or by clever use of C++11
constexpr over std::initializer_list (preferably C++14 constexpr).
[1] https://code.woboq.org/qt5/qtbase/src/corelib/tools/qsimd_x86.cpp.html
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1879115.Ibpzn1huuA%40tjmaciei-mobl1.
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 24 Jul 2018 01:04:48 -0700 (PDT)
Raw View
------=_Part_9405_759615492.1532419488215
Content-Type: multipart/alternative;
boundary="----=_Part_9406_1272083076.1532419488215"
------=_Part_9406_1272083076.1532419488215
Content-Type: text/plain; charset="UTF-8"
>
>
>> Anyways, I think the paper should be more specific about these cases,
>> give examples, make it clear this relocation thing is actually *not*
>> just "optimized move+destroy" as there *can* be observable difference.
>>
>
> Guaranteed elision has an observable difference from mere copy elision.
> But that's the point of the feature.
>
> So too is this. P1144 is not trying to provide a "no observable
> difference" guarantee. The point is to be like guaranteed elision: any
> "observable differences" are stuff you didn't want to have happen anyway.
>
> During the past week, I have been having "fun" trying to extend the C++
object model to cope with memory maps. I think I am beginning to better
appreciate why changing the C++ object model is to be avoided where
possible.
I haven't looked at Arthur's paper in detail yet, but my intent is to
update P1029 into a "this is what we do if we can't agree to do anything
better" proposal.
I should add that the TS wording I am writing for P1031 *hard assumes* the
availability of both relocatability and deterministic exceptions. In fact,
I don't even think it is possible to usefully support memory maps in the
C++ object model without some form of relocatability entering the language,
and relocatability is mandatory for deterministic exceptions to be able to
support legacy exceptions.
The lack of relocatability is becoming an urgent blocker of the future
evolution of C++. Like Executors. We ought to prioritise getting over this
hill.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/5a9a91d9-b76f-4c95-a8c3-9e579a0dfa74%40isocpp.org.
------=_Part_9406_1272083076.1532419488215
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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"><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>=C2=A0</d=
iv><div>Anyways, I think the paper should be more specific about these case=
s, give examples, make it clear this relocation thing is actually <i>not</i=
> just "optimized move+destroy" as there <i>can</i> be observable=
difference.</div></div></blockquote><div><br></div><div>Guaranteed elision=
has an observable difference from mere copy elision. But that's the po=
int of the feature.<br></div><div><br></div><div>So too is this. P1144 is n=
ot trying to provide a "no observable difference" guarantee. The =
point is to be like guaranteed elision: any "observable differences&qu=
ot; are stuff you didn't want to have happen anyway.<br></div><div><br>=
</div></div></blockquote><div>During the past week, I have been having &quo=
t;fun" trying to extend the C++ object model to cope with memory maps.=
I think I am beginning to better appreciate why changing the C++ object mo=
del is to be avoided where possible.</div><div><br></div><div>I haven't=
looked at Arthur's paper in detail yet, but my intent is to update P10=
29 into a "this is what we do if we can't agree to do anything bet=
ter" proposal.</div><div><br></div><div>I should add that the TS wordi=
ng I am writing for P1031 <b>hard assumes</b>=C2=A0the availability of both=
relocatability and deterministic exceptions.=C2=A0In fact, I don't eve=
n think it is possible to usefully support memory maps in the C++ object mo=
del without some form of relocatability entering the language, and relocata=
bility is mandatory for deterministic exceptions to be able to support lega=
cy exceptions.</div><div><br></div><div>The lack of relocatability is becom=
ing an urgent blocker of the future evolution of C++. Like Executors. We ou=
ght to prioritise getting over this hill.</div><div><br></div><div>Niall</d=
iv></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/5a9a91d9-b76f-4c95-a8c3-9e579a0dfa74%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/5a9a91d9-b76f-4c95-a8c3-9e579a0dfa74=
%40isocpp.org</a>.<br />
------=_Part_9406_1272083076.1532419488215--
------=_Part_9405_759615492.1532419488215--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Jul 2018 08:32:53 -0700 (PDT)
Raw View
------=_Part_8916_1033470847.1532446373090
Content-Type: multipart/alternative;
boundary="----=_Part_8917_370694360.1532446373090"
------=_Part_8917_370694360.1532446373090
Content-Type: text/plain; charset="UTF-8"
On Tuesday, July 24, 2018 at 4:04:48 AM UTC-4, Niall Douglas wrote:
>
>
>>> Anyways, I think the paper should be more specific about these cases,
>>> give examples, make it clear this relocation thing is actually *not*
>>> just "optimized move+destroy" as there *can* be observable difference.
>>>
>>
>> Guaranteed elision has an observable difference from mere copy elision.
>> But that's the point of the feature.
>>
>> So too is this. P1144 is not trying to provide a "no observable
>> difference" guarantee. The point is to be like guaranteed elision: any
>> "observable differences" are stuff you didn't want to have happen anyway.
>>
>> During the past week, I have been having "fun" trying to extend the C++
> object model to cope with memory maps. I think I am beginning to better
> appreciate why changing the C++ object model is to be avoided where
> possible.
>
> I haven't looked at Arthur's paper in detail yet, but my intent is to
> update P1029 into a "this is what we do if we can't agree to do anything
> better" proposal.
>
> I should add that the TS wording I am writing for P1031 *hard assumes* the
> availability of both relocatability and deterministic exceptions. In fact,
> I don't even think it is possible to usefully support memory maps in the
> C++ object model without some form of relocatability entering the language,
> and relocatability is mandatory for deterministic exceptions to be able to
> support legacy exceptions.
>
I fail to see how that latter statement is true. Static exceptions as
defined by P0709 can shepherd legacy exceptions by storing a pointer to an
`exception_ptr` object. And unpacking an `exception_ptr` is already a
proposal: P1066. So relocation is not essential to having dynamic
exceptions interop with static ones.
Relocation only matters to static exceptions in so far as we want to allow
user-defined types to be statically thrown. So long as we follow P0709,
which only allows throwing `std::error`, treating statically throwing other
types as a possible extension rather than a required feature, relocation is
entirely orthogonal to static exceptions.
And even if we allow throwing other types, relocation is merely an
*optimization* of this. P0709 only requires that a static exception type is
noexcept moveable, not relocatable. Defining a relocatable type merely
allows more types to be passed through registers rather than a stack object
(`std::error` can be permitted to work via standard library fiat) and
improve efficiency. But it is not a requirement for throwing user-defined
types.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7007bed7-76ca-430b-ae61-eccdbbba093c%40isocpp.org.
------=_Part_8917_370694360.1532446373090
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 24, 2018 at 4:04:48 AM UTC-4, Niall Dougl=
as 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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0</div><div>Anyways, I think t=
he paper should be more specific about these cases, give examples, make it =
clear this relocation thing is actually <i>not</i> just "optimized mov=
e+destroy" as there <i>can</i> be observable difference.</div></div></=
blockquote><div><br></div><div>Guaranteed elision has an observable differe=
nce from mere copy elision. But that's the point of the feature.<br></d=
iv><div><br></div><div>So too is this. P1144 is not trying to provide a &qu=
ot;no observable difference" guarantee. The point is to be like guaran=
teed elision: any "observable differences" are stuff you didn'=
;t want to have happen anyway.<br></div><div><br></div></div></blockquote><=
div>During the past week, I have been having "fun" trying to exte=
nd the C++ object model to cope with memory maps. I think I am beginning to=
better appreciate why changing the C++ object model is to be avoided where=
possible.</div><div><br></div><div>I haven't looked at Arthur's pa=
per in detail yet, but my intent is to update P1029 into a "this is wh=
at we do if we can't agree to do anything better" proposal.</div><=
div><br></div><div>I should add that the TS wording I am writing for P1031 =
<b>hard assumes</b>=C2=A0the availability of both relocatability and determ=
inistic exceptions.=C2=A0In fact, I don't even think it is possible to =
usefully support memory maps in the C++ object model without some form of r=
elocatability entering the language, and relocatability is mandatory for de=
terministic exceptions to be able to support legacy exceptions.</div></div>=
</blockquote><div><br></div><div>I fail to see how that latter statement is=
true. Static exceptions as defined by P0709 can shepherd legacy exceptions=
by storing a pointer to an `exception_ptr` object. And unpacking an `excep=
tion_ptr` is already a proposal: P1066. So relocation is not essential to h=
aving dynamic exceptions interop with static ones.</div><br><div>Relocation=
only matters to static exceptions in so far as we want to allow user-defin=
ed types to be statically thrown. So long as we follow P0709, which only al=
lows throwing `std::error`, treating statically throwing other types as a p=
ossible extension rather than a required feature, relocation is entirely or=
thogonal to static exceptions.</div><div><br></div><div>And even if we allo=
w throwing other types, relocation is merely an <i>optimization</i> of this=
.. P0709 only requires that a static exception type is noexcept moveable, no=
t relocatable. Defining a relocatable type merely allows more types to be p=
assed through registers rather than a stack object (`std::error` can be per=
mitted to work via standard library fiat) and improve efficiency. But it is=
not a requirement for throwing user-defined types.<br></div><br></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7007bed7-76ca-430b-ae61-eccdbbba093c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7007bed7-76ca-430b-ae61-eccdbbba093c=
%40isocpp.org</a>.<br />
------=_Part_8917_370694360.1532446373090--
------=_Part_8916_1033470847.1532446373090--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 24 Jul 2018 10:45:58 -0700 (PDT)
Raw View
------=_Part_9179_1896598801.1532454359000
Content-Type: multipart/alternative;
boundary="----=_Part_9180_1090694969.1532454359000"
------=_Part_9180_1090694969.1532454359000
Content-Type: text/plain; charset="UTF-8"
>
> and relocatability is mandatory for deterministic exceptions to be able
>> to support legacy exceptions.
>>
>
> I fail to see how that latter statement is true. Static exceptions as
> defined by P0709 can shepherd legacy exceptions by storing a pointer to an
> `exception_ptr` object. And unpacking an `exception_ptr` is already a
> proposal: P1066. So relocation is not essential to having dynamic
> exceptions interop with static ones.
>
How does one manage the lifetime of the exception_ptr object if std::error
cannot call a non-trivial destructor on its final destruction?
You can give std::error a non-trivial destructor without relocatability,
but then you ruin most of the gains of adopting value based exceptions.
>
> Relocation only matters to static exceptions in so far as we want to allow
> user-defined types to be statically thrown. So long as we follow P0709,
> which only allows throwing `std::error`, treating statically throwing other
> types as a possible extension rather than a required feature, relocation is
> entirely orthogonal to static exceptions.
>
I'm curious to see how you conceive a std::error under your mental model of
how value based exceptions would be implemented. Can you describe your
preferred formulation of the standard error object?
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/d799956c-1490-4800-8d54-fced2830a0b8%40isocpp.org.
------=_Part_9180_1090694969.1532454359000
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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"><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>=C2=A0and=
relocatability is mandatory for deterministic exceptions to be able to sup=
port legacy exceptions.</div></div></blockquote><div><br></div><div>I fail =
to see how that latter statement is true. Static exceptions as defined by P=
0709 can shepherd legacy exceptions by storing a pointer to an `exception_p=
tr` object. And unpacking an `exception_ptr` is already a proposal: P1066. =
So relocation is not essential to having dynamic exceptions interop with st=
atic ones.</div></div></blockquote><div><br></div><div>How does one manage =
the lifetime of the exception_ptr object if std::error cannot call a non-tr=
ivial destructor on its final destruction?</div><div><br></div><div>You can=
give std::error a non-trivial destructor without relocatability, but then =
you ruin most of the gains of adopting value based exceptions.</div><div>=
=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><=
br><div>Relocation only matters to static exceptions in so far as we want t=
o allow user-defined types to be statically thrown. So long as we follow P0=
709, which only allows throwing `std::error`, treating statically throwing =
other types as a possible extension rather than a required feature, relocat=
ion is entirely orthogonal to static exceptions.</div></div></blockquote><d=
iv><br></div><div>I'm curious to see how you conceive a std::error unde=
r your mental model of how value based exceptions would be implemented. Can=
you describe your preferred formulation of the standard error object?</div=
><div><br></div><div>Niall</div><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/d799956c-1490-4800-8d54-fced2830a0b8%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d799956c-1490-4800-8d54-fced2830a0b8=
%40isocpp.org</a>.<br />
------=_Part_9180_1090694969.1532454359000--
------=_Part_9179_1896598801.1532454359000--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Jul 2018 11:33:38 -0700 (PDT)
Raw View
------=_Part_9137_1464071150.1532457218869
Content-Type: multipart/alternative;
boundary="----=_Part_9138_1140445198.1532457218870"
------=_Part_9138_1140445198.1532457218870
Content-Type: text/plain; charset="UTF-8"
On Tuesday, July 24, 2018 at 1:45:59 PM UTC-4, Niall Douglas wrote:
>
> and relocatability is mandatory for deterministic exceptions to be able
>>> to support legacy exceptions.
>>>
>>
>> I fail to see how that latter statement is true. Static exceptions as
>> defined by P0709 can shepherd legacy exceptions by storing a pointer to an
>> `exception_ptr` object. And unpacking an `exception_ptr` is already a
>> proposal: P1066. So relocation is not essential to having dynamic
>> exceptions interop with static ones.
>>
>
> How does one manage the lifetime of the exception_ptr object if std::error
> cannot call a non-trivial destructor on its final destruction?
>
Compiler magic. `std::error` can do it because the standard *says* that it
can.
You can give std::error a non-trivial destructor without relocatability,
> but then you ruin most of the gains of adopting value based exceptions.
>
> Relocation only matters to static exceptions in so far as we want to allow
>> user-defined types to be statically thrown. So long as we follow P0709,
>> which only allows throwing `std::error`, treating statically throwing other
>> types as a possible extension rather than a required feature, relocation is
>> entirely orthogonal to static exceptions.
>>
>
> I'm curious to see how you conceive a std::error under your mental model
> of how value based exceptions would be implemented. Can you describe your
> preferred formulation of the standard error object?
>
I don't have a model; P0709 does. My "preferred formulation" is merely
"Section 4.1 of that document".
My point is that static exceptions don't have to allow arbitrary
user-defined types to be "relocatable" or have a general concept of what
that means. The core feature merely needs to define how `std::error`
operates as a type. And if that means it has capabilities that other
user-defined types cannot possess, then so be it.
Obviously, we'd *prefer* that user-defined types could do magical things
too. But it's not blocking anything.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/90268bf3-8f9e-4621-8225-0a5f5ac29760%40isocpp.org.
------=_Part_9138_1140445198.1532457218870
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 24, 2018 at 1:45:59 PM UTC-4, Niall Dougl=
as 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"><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-le=
ft:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"g=
mail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;=
padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0and relocatability is mandato=
ry for deterministic exceptions to be able to support legacy exceptions.</d=
iv></div></blockquote><div><br></div><div>I fail to see how that latter sta=
tement is true. Static exceptions as defined by P0709 can shepherd legacy e=
xceptions by storing a pointer to an `exception_ptr` object. And unpacking =
an `exception_ptr` is already a proposal: P1066. So relocation is not essen=
tial to having dynamic exceptions interop with static ones.</div></div></bl=
ockquote><div><br></div><div>How does one manage the lifetime of the except=
ion_ptr object if std::error cannot call a non-trivial destructor on its fi=
nal destruction?</div></div></blockquote><div><br></div><div>Compiler magic=
.. `std::error` can do it because the standard <i>says</i> that it can.<br><=
/div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;ma=
rgin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div></div><div>You can give std::error a non-trivial destructor w=
ithout relocatability, but then you ruin most of the gains of adopting valu=
e based exceptions.</div><div><br></div><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><div>Relocation only matters to static exceptions in =
so far as we want to allow user-defined types to be statically thrown. So l=
ong as we follow P0709, which only allows throwing `std::error`, treating s=
tatically throwing other types as a possible extension rather than a requir=
ed feature, relocation is entirely orthogonal to static exceptions.</div></=
div></blockquote><div><br></div><div>I'm curious to see how you conceiv=
e a std::error under your mental model of how value based exceptions would =
be implemented. Can you describe your preferred formulation of the standard=
error object?</div></div></blockquote><div><br></div><div>I don't have=
a model; P0709 does. My "preferred formulation" is merely "=
Section 4.1 of that document".</div><div><br></div><div>My point is th=
at static exceptions don't have to allow arbitrary user-defined types t=
o be "relocatable" or have a general concept of what that means. =
The core feature merely needs to define how `std::error` operates as a type=
.. And if that means it has capabilities that other user-defined types canno=
t possess, then so be it.</div><div><br></div><div>Obviously, we'd <i>p=
refer</i> that user-defined types could do magical things too. But it's=
not blocking anything.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/90268bf3-8f9e-4621-8225-0a5f5ac29760%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/90268bf3-8f9e-4621-8225-0a5f5ac29760=
%40isocpp.org</a>.<br />
------=_Part_9138_1140445198.1532457218870--
------=_Part_9137_1464071150.1532457218869--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 24 Jul 2018 11:41:26 -0700 (PDT)
Raw View
------=_Part_9334_2130702773.1532457686808
Content-Type: multipart/alternative;
boundary="----=_Part_9335_1478229804.1532457686808"
------=_Part_9335_1478229804.1532457686808
Content-Type: text/plain; charset="UTF-8"
On Tuesday, July 24, 2018 at 2:33:39 PM UTC-4, Nicol Bolas wrote:
>
> On Tuesday, July 24, 2018 at 1:45:59 PM UTC-4, Niall Douglas wrote:
>>
>> and relocatability is mandatory for deterministic exceptions to be able
>>>> to support legacy exceptions.
>>>>
>>>
>>> I fail to see how that latter statement is true. Static exceptions as
>>> defined by P0709 can shepherd legacy exceptions by storing a pointer to an
>>> `exception_ptr` object. And unpacking an `exception_ptr` is already a
>>> proposal: P1066. So relocation is not essential to having dynamic
>>> exceptions interop with static ones.
>>>
>>
>> How does one manage the lifetime of the exception_ptr object if
>> std::error cannot call a non-trivial destructor on its final destruction?
>>
>
> Compiler magic. `std::error` can do it because the standard *says* that
> it can.
>
I think I misunderstood what you were saying. The answer is still "compiler
magic", but a different form.
If you're talking about the throwing of `std::error` as an exception and
its propagation up the call graph, that is a function of the static
exception machinery. This is conceptually based on return values and the
like, but the compiler is intimately involved. Therefore, it can choose to
call `std::error`'s non-trivial destructor or not, as it sees fit, in a
static way. After all, if it's "copying" the object from the current stack
to the caller's value, then it knows that it can just do a memcpy and not
call the destructor. Or stick it in a register. And that's a static thing.
Once the object materializes in a way you can inspect it, then it acts like
a regular object. Copying it bumps the reference counter, if one exists.
Destroying it decrements the reference counter if it exists. And the like.
The important compiler magic for `std::error` is its treatment during
exception propagation, which user code cannot impinge upon.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/dd4466fe-3b04-4e65-b89f-83ddbb07e75f%40isocpp.org.
------=_Part_9335_1478229804.1532457686808
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, July 24, 2018 at 2:33:39 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;"><div dir=3D"ltr">On Tue=
sday, July 24, 2018 at 1:45:59 PM UTC-4, Niall Douglas wrote:<blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote=
" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr"><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>=C2=A0and relocatability is mandatory for deterministic excep=
tions to be able to support legacy exceptions.</div></div></blockquote><div=
><br></div><div>I fail to see how that latter statement is true. Static exc=
eptions as defined by P0709 can shepherd legacy exceptions by storing a poi=
nter to an `exception_ptr` object. And unpacking an `exception_ptr` is alre=
ady a proposal: P1066. So relocation is not essential to having dynamic exc=
eptions interop with static ones.</div></div></blockquote><div><br></div><d=
iv>How does one manage the lifetime of the exception_ptr object if std::err=
or cannot call a non-trivial destructor on its final destruction?</div></di=
v></blockquote><div><br></div><div>Compiler magic. `std::error` can do it b=
ecause the standard <i>says</i> that it can.<br></div></div></blockquote><d=
iv><br></div><div>I think I misunderstood what you were saying. The answer =
is still "compiler magic", but a different form.</div><div><br></=
div><div>If you're talking about the throwing of `std::error` as an exc=
eption and its propagation up the call graph, that is a function of the sta=
tic exception machinery. This is conceptually based on return values and th=
e like, but the compiler is intimately involved. Therefore, it can choose t=
o call `std::error`'s non-trivial destructor or not, as it sees fit, in=
a static way. After all, if it's "copying" the object from t=
he current stack to the caller's value, then it knows that it can just =
do a memcpy and not call the destructor. Or stick it in a register. And tha=
t's a static thing.</div><div><br></div><div>Once the object materializ=
es in a way you can inspect it, then it acts like a regular object. Copying=
it bumps the reference counter, if one exists. Destroying it decrements th=
e reference counter if it exists. And the like.</div><div><br></div><div>Th=
e important compiler magic for `std::error` is its treatment during excepti=
on propagation, which user code cannot impinge upon.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dd4466fe-3b04-4e65-b89f-83ddbb07e75f%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dd4466fe-3b04-4e65-b89f-83ddbb07e75f=
%40isocpp.org</a>.<br />
------=_Part_9335_1478229804.1532457686808--
------=_Part_9334_2130702773.1532457686808--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 24 Jul 2018 11:44:43 -0700
Raw View
--000000000000cf757b0571c32772
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Tue, Jul 24, 2018 at 10:45 AM, Niall Douglas <nialldouglas14@gmail.com>
wrote:
> and relocatability is mandatory for deterministic exceptions to be able
>>> to support legacy exceptions.
>>>
>>
>> I fail to see how that latter statement is true. Static exceptions as
>> defined by P0709 can shepherd legacy exceptions by storing a pointer to =
an
>> `exception_ptr` object. And unpacking an `exception_ptr` is already a
>> proposal: P1066. So relocation is not essential to having dynamic
>> exceptions interop with static ones.
>>
>
> How does one manage the lifetime of the exception_ptr object if std::erro=
r
> cannot call a non-trivial destructor on its final destruction?
> You can give std::error a non-trivial destructor without relocatability,
> but then you ruin most of the gains of adopting value based exceptions.
>
I see at least two reasonable positions one might hold here:
(A), if you don't permit throwing user-defined error types, then it's
feasible for the vendor to make std::error "slightly magic" to the compiler
=E2=80=94 maybe just give it [[clang::trivial_abi]] so it can be passed in
registers, and let the optimizer take care of eliminating the code that
comes from exception_ptr's SMFs. (This is what Nicol's been saying.)
(B), even if you do permit throwing user-defined error types, you don't
*necessarily* need "trivial relocatability" to be a thing in the *language*=
..
There is some precedent for specifying a Concept as a bag of syntactic
constraints *plus* a handwavey semantic requirement: "SuitableForError
requires MoveConstructible && Destructible, plus if you move-construct it
followed by a destruct of the source, that whole thing must be tantamount
to a memcpy." We actually have a very similar constraint today with some
of the atomic<T> stuff (although for those who've seen my talk
<https://www.youtube.com/watch?v=3DMWBfmmg8-Yo>, the atomic<T> stuff is mor=
e
about trivially *comparable* than trivially copyable or trivially
relocatable).
My position is that neither (A) nor (B) are *good*; (A) says "throw the
problem on the optimizer =E2=80=94 the failure mode is that your code is sl=
ower
than you thought it'd be" and (B) says "throw the specification problem
onto implementors =E2=80=94 the failure mode is that your code has undefine=
d
behavior when you thought it wouldn't." But I think they're plausible
enough positions for someone else to take that I personally wouldn't go as
far as
> In fact, I don't even think it is possible to usefully support memory
maps in the C++ object model
> without some form of relocatability entering the language, and
relocatability is mandatory
> for deterministic exceptions to be able to support legacy exceptions.
Niall, could you elaborate a little on how relocatability is relevant to
memory maps? (Bearing in mind that I don't know exactly what you mean by
"memory map".)
I can certainly imagine a chain of reasoning like this...
(Niall is implementing afio) -> (Niall wants to use the new error-handling
scheme) -> (the new error-handling scheme seems to require something like
"trivially relocatable" to get the best performance) -> (Niall wants the
best performance) -> (afio requires something like "trivially relocatable")
....but this chain is *very* weak and circumstantial, IMO. If there's
something specific to the problem domain that involves "relocation," I'd
like to know about it for my paper.
=E2=80=93Arthur
P.S. =E2=80=94 Re naming, I do worry =E2=80=94 not about stepping on the EL=
F notion of
"relocations" =E2=80=94 but on the stuff done by e.g. Boost.Interprocess an=
d Bob
Steagall, where you can take a whole custom-allocated data structure based
at address 0xfoo and *share* the whole shebang (including all its pointers
and pointees) into a different process based at some other address 0xbar,
and still expect it to run correctly. This is the use-case for
boost::interprocess::offset_ptr, and could plausibly be described as a kind
of "relocation" (in the English-word sense). However,
boost::interprocess::offset_ptr (or any object recursively containing
offset_ptr) is the canonical example of a *non*-trivially-relocatable class
type in the P1029 and P1144 senses.
--=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/CADvuK0L4uszScZCEg7rAB0vizQx29Eyhcb9xMnnpx6R-U14=
5uQ%40mail.gmail.com.
--000000000000cf757b0571c32772
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tue, Jul 24, 2018 at 10:45 AM, Niall Douglas <span dir=
=3D"ltr"><<a href=3D"mailto:nialldouglas14@gmail.com" target=3D"_blank">=
nialldouglas14@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-=
left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span class=
=3D"gmail-"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0=
..8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(20=
4,204,204);padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-st=
yle:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"=
ltr"><div>=C2=A0and relocatability is mandatory for deterministic exception=
s to be able to support legacy exceptions.</div></div></blockquote><div><br=
></div><div>I fail to see how that latter statement is true. Static excepti=
ons as defined by P0709 can shepherd legacy exceptions by storing a pointer=
to an `exception_ptr` object. And unpacking an `exception_ptr` is already =
a proposal: P1066. So relocation is not essential to having dynamic excepti=
ons interop with static ones.</div></div></blockquote><div><br></div></span=
><div>How does one manage the lifetime of the exception_ptr object if std::=
error cannot call a non-trivial destructor on its final destruction?</div><=
div>You can give std::error a non-trivial destructor without relocatability=
, but then you ruin most of the gains of adopting value based exceptions.</=
div><span class=3D"gmail-"><div></div></span></div></blockquote><div><br></=
div><div>I see at least two reasonable positions one might hold here:</div>=
<div><br></div><div>(A), if you don't permit throwing user-defined erro=
r types, then it's feasible for the vendor to make std::error "sli=
ghtly magic" to the compiler =E2=80=94 maybe just give it [[clang::tri=
vial_abi]] so it can be passed in registers, and let the optimizer take car=
e of eliminating the code that comes from exception_ptr's SMFs. =C2=A0(=
This is what Nicol's been saying.)</div><div><br></div><div>(B), even i=
f you do permit throwing user-defined error types, you don't <i>necessa=
rily</i> need "trivial relocatability" to be a thing in the <i>la=
nguage</i>. There is some precedent for specifying a Concept as a bag of sy=
ntactic constraints <i>plus</i> a handwavey semantic requirement: "Sui=
tableForError requires MoveConstructible && Destructible, plus if y=
ou move-construct it followed by a destruct of the source, that whole thing=
must be tantamount to a memcpy." =C2=A0We actually have a very simila=
r constraint today with some of the atomic<T> stuff (although for tho=
se who've seen <a href=3D"https://www.youtube.com/watch?v=3DMWBfmmg8-Yo=
">my talk</a>, the atomic<T> stuff is more about trivially <i>compara=
ble</i> than trivially copyable or trivially relocatable).</div><div><br></=
div><div>My position is that neither (A) nor (B) are <i>good</i>; (A) says =
"throw the problem on the optimizer =E2=80=94 the failure mode is that=
your code is slower than you thought it'd be" and (B) says "=
throw the specification problem onto implementors =E2=80=94 the failure mod=
e is that your code has undefined behavior when you thought it wouldn't=
.." But I think they're plausible enough positions for someone else=
to take that I personally wouldn't go as far as</div><div><br></div><d=
iv>>=C2=A0<span style=3D"color:rgb(80,0,80);font-size:12.800000190734863=
px">In fact, I don't even think it is possible to usefully support memo=
ry maps in the C++ object model</span></div><div><span style=3D"color:rgb(8=
0,0,80);font-size:12.800000190734863px">> without some form of relocatab=
ility entering the language, and relocatability is mandatory</span></div><d=
iv><span style=3D"color:rgb(80,0,80);font-size:12.800000190734863px">> f=
or</span><span style=3D"color:rgb(80,0,80);font-size:12.800000190734863px">=
=C2=A0deterministic exceptions to be able to support legacy exceptions.</sp=
an></div><div><br></div><div>Niall, could you elaborate a little on how rel=
ocatability is relevant to memory maps? =C2=A0(Bearing in mind that I don&#=
39;t know exactly what you mean by "memory map".)</div><div><br><=
/div><div>I can certainly imagine a chain of reasoning like this...</div><d=
iv>(Niall is implementing afio) -> (Niall wants to use the new error-han=
dling scheme) ->=C2=A0(the new error-handling scheme seems to require so=
mething like "trivially relocatable" to get the best performance)=
-> (Niall wants the best performance) ->=C2=A0(afio requires somethi=
ng like "trivially relocatable")<br></div><div>...but this chain =
is <i>very</i> weak and circumstantial, IMO.=C2=A0 If there's something=
specific to the problem domain that involves "relocation," I'=
;d like to know about it for my paper.</div><div><br></div><div>=E2=80=93Ar=
thur</div><div><br></div><div>P.S. =E2=80=94 Re naming, I do worry =E2=80=
=94 not about stepping on the ELF notion of "relocations" =E2=80=
=94 but on the stuff done by e.g. Boost.Interprocess and Bob Steagall, wher=
e you can take a whole custom-allocated data structure based at address 0xf=
oo and <i>share</i> the whole shebang (including all its pointers and point=
ees) into a different process based at some other address 0xbar, and still =
expect it to run correctly.=C2=A0 This is the use-case for boost::interproc=
ess::offset_ptr, and could plausibly be described as a kind of "reloca=
tion" (in the English-word sense).=C2=A0 However, boost::interprocess:=
:offset_ptr (or any object recursively containing offset_ptr) is the canoni=
cal example of a <i><b>non</b></i>-trivially-relocatable class type in the =
P1029 and P1144 senses.</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" 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/CADvuK0L4uszScZCEg7rAB0vizQx29Eyhcb9x=
Mnnpx6R-U145uQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0L4uszScZCE=
g7rAB0vizQx29Eyhcb9xMnnpx6R-U145uQ%40mail.gmail.com</a>.<br />
--000000000000cf757b0571c32772--
.
Author: inkwizytoryankes@gmail.com
Date: Tue, 24 Jul 2018 16:24:13 -0700 (PDT)
Raw View
------=_Part_9215_1909990573.1532474653917
Content-Type: multipart/alternative;
boundary="----=_Part_9216_1356773970.1532474653918"
------=_Part_9216_1356773970.1532474653918
Content-Type: text/plain; charset="UTF-8"
On Tuesday, July 24, 2018 at 7:45:59 PM UTC+2, Niall Douglas wrote:
>
> and relocatability is mandatory for deterministic exceptions to be able
>>> to support legacy exceptions.
>>>
>>
>> I fail to see how that latter statement is true. Static exceptions as
>> defined by P0709 can shepherd legacy exceptions by storing a pointer to an
>> `exception_ptr` object. And unpacking an `exception_ptr` is already a
>> proposal: P1066. So relocation is not essential to having dynamic
>> exceptions interop with static ones.
>>
>
> How does one manage the lifetime of the exception_ptr object if std::error
> cannot call a non-trivial destructor on its final destruction?
>
> You can give std::error a non-trivial destructor without relocatability,
> but then you ruin most of the gains of adopting value based exceptions.
>
>
In recent discussion about your `_Fails` proposal I suggested spiting
`std::error` and thing that is pass through exception mechanism
(`cxx_std_error` that is C struct).
Similar idea to transforming `std::vector<std::unique_ptr<T>>` to
`unique_ptr_vector : std::vector<T*>` where `unique_ptr_vector` handle
invariants similar to `unique_ptr` for each member.
With this resizing is simply doing `memcpy` because you handle POD types
internally.
std::unique_ptr<T> <--> T*
std::error <--> cxx_std_error
We will lose encapsulation because we will expose raw state but if used
only C++ exceptions in most case this conversion will be done automatically
by compiler (using user defined constructors and conversion functions).
https://groups.google.com/a/isocpp.org/d/msg/std-proposals/-vXIn8rLza8/1hdZZa2bBAAJ
>
>> Relocation only matters to static exceptions in so far as we want to
>> allow user-defined types to be statically thrown. So long as we follow
>> P0709, which only allows throwing `std::error`, treating statically
>> throwing other types as a possible extension rather than a required
>> feature, relocation is entirely orthogonal to static exceptions.
>>
>
> I'm curious to see how you conceive a std::error under your mental model
> of how value based exceptions would be implemented. Can you describe your
> preferred formulation of the standard error object?
>
> Niall
>
>
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/a61367f0-2da1-46ca-a6e8-521a03132238%40isocpp.org.
------=_Part_9216_1356773970.1532474653918
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, July 24, 2018 at 7:45:59 PM UTC+2, Nia=
ll Douglas 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"><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"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div dir=3D"ltr"><div>=C2=A0and relocatability is=
mandatory for deterministic exceptions to be able to support legacy except=
ions.</div></div></blockquote><div><br></div><div>I fail to see how that la=
tter statement is true. Static exceptions as defined by P0709 can shepherd =
legacy exceptions by storing a pointer to an `exception_ptr` object. And un=
packing an `exception_ptr` is already a proposal: P1066. So relocation is n=
ot essential to having dynamic exceptions interop with static ones.</div></=
div></blockquote><div><br></div><div>How does one manage the lifetime of th=
e exception_ptr object if std::error cannot call a non-trivial destructor o=
n its final destruction?</div><div><br></div><div>You can give std::error a=
non-trivial destructor without relocatability, but then you ruin most of t=
he gains of adopting value based exceptions.</div><div>=C2=A0</div></div></=
blockquote><div><br></div><div>In recent discussion about your `_Fails` pro=
posal I suggested spiting `std::error` and thing that is pass through excep=
tion mechanism (`cxx_std_error` that is C struct).</div><div>Similar idea t=
o transforming `std::vector<std::unique_ptr<T>>` to `unique_ptr=
_vector : std::vector<T*>` where `unique_ptr_vector` handle invariant=
s similar to `unique_ptr` for each member.</div><div>With this resizing is =
simply doing `memcpy` because you handle POD types internally.</div><div><b=
r></div><div>std::unique_ptr<T> <--> T*</div><div>std::error &l=
t;--> cxx_std_error</div><div><br></div><div>We will lose encapsulation =
because we will expose raw state but if used only C++ exceptions in most ca=
se this conversion will be done automatically by compiler (using user defin=
ed constructors and conversion functions).<br></div><div><div><br></div><di=
v>https://groups.google.com/a/isocpp.org/d/msg/std-proposals/-vXIn8rLza8/1h=
dZZa2bBAAJ</div></div><div>=C2=A0</div><blockquote class=3D"gmail_quote" st=
yle=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-lef=
t: 1ex;"><div dir=3D"ltr"><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"><br><div>Relocation only matters to static exceptions in so far as=
we want to allow user-defined types to be statically thrown. So long as we=
follow P0709, which only allows throwing `std::error`, treating statically=
throwing other types as a possible extension rather than a required featur=
e, relocation is entirely orthogonal to static exceptions.</div></div></blo=
ckquote><div><br></div><div>I'm curious to see how you conceive a std::=
error under your mental model of how value based exceptions would be implem=
ented. Can you describe your preferred formulation of the standard error ob=
ject?</div><div><br></div><div>Niall</div><br></div></blockquote><div><br><=
/div><div><br></div><div>=C2=A0</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/a61367f0-2da1-46ca-a6e8-521a03132238%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a61367f0-2da1-46ca-a6e8-521a03132238=
%40isocpp.org</a>.<br />
------=_Part_9216_1356773970.1532474653918--
------=_Part_9215_1909990573.1532474653917--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Tue, 24 Jul 2018 23:42:13 -0700
Raw View
--000000000000ca00940571cd2db1
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
> On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@gmail.com wrote:
>>
>> On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>>>
>>> But as Arthur noted, this definition would exempt an entire category of
>>> objects like `std::list`, where move does not leave them in a "trivial"
>>> state. The P1144 definition of relocation is that "move+destroy" is
>>> equivalent to "memcpy+drop". That's not the same thing as declaring tha=
t
>>> movement leaves the object in a "trivial state".
>>>
>>
>> I see, so 1144 "works" even if after 'move', the object needs to be
>> non-trivially destroyed. Yeah, my observations do not apply then.
>>
>> [...]
>>
>
> But you're right, that it should talk about cases like `std::list`. And
> I'm rather surprised that it didn't bring them up.
>
Well, here's some revolting news: `std::list` *is not* trivially
relocatable on any vendor today! I have just added a new subsection to
Appendix C, giving `std::list` alongside my other examples of
non-trivially-relocatable types:
=3D=3D=3D=3D=3D
std::list needs somewhere to store its "past-the-end" node, commonly
referred to as the "sentinel node." If the sentinel node is allocated on
the heap, then std::list can be trivially relocatable; but if the sentinel
node is placed within the list object itself (as happens on libc++ and
libstdc++), then relocating the list object will necessitate fixing up a
pair of pointers elsewhere on the heap. This fixup cannot be simulated by
memcpy.
Traditional implementations of std::set and std::map also store a
"past-the-end" node inside themselves and thus also fall into this category=
..
struct node {
node *prev_ =3D nullptr;
node *next_ =3D nullptr;
};
struct list {
node n_;
iterator begin() { return iterator(n_.next_); }
iterator end() { return iterator(&n_); }
list(list&& l) {
if (l.n_.next_) l.n_.next_->prev_ =3D &n_; // fixup
if (l.n_.prev_) l.n_.prev_->next_ =3D &n_; // fixup
n_ =3D l.n_;
l.n_ =3D node{};
}
// ...
};
=3D=3D=3D=3D=3D
Anyone got any thoughts on std::list? I'm shocked (in a
"why-didn't-you-do-my-homework-for-me" way ;)) that the non-trivial
relocatability of `list`, `set`, map`, etc. wasn't raised in any previous
papers or mailing-list discussions on the topic. Indeed, we've kind of been
using `list` as a poster child for relocatability. And I believe it *is*
trivially relocatable if you let it allocate a sentinel node on the heap;
but no vendor actually does that, AFAIK. Somehow, its (super obvious in
hindsight) non-trivial relocatability never impinged on my consciousness
until today.
There remains a category of types =E2=80=94 such as a C++03-era-copy-only
`shared_ptr` =E2=80=94 whose "moved-from" states are not "noop destructible=
"
but which nevertheless are trivially relocatable. However, I am kicking
myself over the loss of std::list, std::map, and std::set.
=E2=80=93Arthur
--=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/CADvuK0LG4qKeRF4aGWC-8wG2z8-a19KPmOufo_hjr-4HA23=
iZQ%40mail.gmail.com.
--000000000000ca00940571cd2db1
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <span dir=3D"=
ltr"><<a href=3D"mailto:jmckesson@gmail.com" target=3D"_blank">jmckesson=
@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra"><div class=
=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px =
0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:r=
gb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail=
-h5">On Monday, July 23, 2018 at 3:00:55 PM UTC-4, <a href=3D"mailto:mihail=
n...@gmail.com" target=3D"_blank">mihailn...@gmail.com</a> wrote:<blockquot=
e class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width=
:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-lef=
t:1ex"><div dir=3D"ltr">On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol=
Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px =
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(2=
04,204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><div>But as Arthu=
r noted, this definition would exempt an entire category of objects like `s=
td::list`, where move does not leave them in a "trivial" state. T=
he P1144 definition of relocation is that "move+destroy" is equiv=
alent to "memcpy+drop". That's not the same thing as declarin=
g that movement leaves the object in a "trivial state".<br></div>=
</div></blockquote><div>=C2=A0</div><div>I see, so 1144 "works" e=
ven if after 'move', the object needs to be non-trivially destroyed=
.. Yeah, my observations do not apply then.</div><div><br></div><div>[...]</=
div></div></blockquote></div></div><div><br></div><div>But you're right=
, that it should talk about cases like `std::list`. And I'm rather surp=
rised that it didn't bring them up.</div></div></blockquote><div><br></=
div><div>Well, here's some revolting news: `std::list` <i><b>is not</b>=
</i> trivially relocatable on any vendor today!=C2=A0=C2=A0I have just adde=
d a new subsection to Appendix C, giving `std::list` alongside my other exa=
mples of non-trivially-relocatable types:</div><div><br></div><div>=3D=3D=
=3D=3D=3D</div><div><div>std::list needs somewhere to store its "past-=
the-end" node, commonly referred to as the "sentinel node." =
If the sentinel node is allocated on the heap, then std::list can be trivia=
lly relocatable; but if the sentinel node is placed within the list object =
itself (as happens on libc++ and libstdc++), then relocating the list objec=
t will necessitate fixing up a pair of pointers elsewhere on the heap. This=
fixup cannot be simulated by memcpy.</div><div><br></div><div>Traditional =
implementations of std::set and std::map also store a "past-the-end&qu=
ot; node inside themselves and thus also fall into this category.</div><div=
><br></div><div>=C2=A0struct node {</div><div>=C2=A0 =C2=A0 node *prev_ =3D=
nullptr;</div><div>=C2=A0 =C2=A0 node *next_ =3D nullptr;</div><div>};</di=
v><div>struct list {</div><div>=C2=A0 =C2=A0 node n_;</div><div>=C2=A0 =C2=
=A0 iterator begin() { return iterator(n_.next_); }</div><div>=C2=A0 =C2=A0=
iterator end() { return iterator(&n_); }</div><div>=C2=A0 =C2=A0 list(=
list&& l) {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (l.n_.next_) l=
..n_.next_->prev_ =3D &n_; =C2=A0// fixup</div><div>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 if (l.n_.prev_) l.n_.prev_->next_ =3D &n_; =C2=A0// fixup=
</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 n_ =3D l.n_;</div><div>=C2=A0 =C2=A0=
=C2=A0 =C2=A0 l.n_ =3D node{};</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =
=C2=A0 // ...</div><div>};</div></div><div>=3D=3D=3D=3D=3D</div><div><br></=
div><div>Anyone got any thoughts on std::list?=C2=A0 I'm shocked (in a =
"why-didn't-you-do-my-homework-for-me" way ;)) that the non-t=
rivial relocatability of `list`, `set`, map`, etc. wasn't raised in any=
previous papers or mailing-list discussions on the topic. Indeed, we'v=
e kind of been using `list` as a poster child for relocatability. And I bel=
ieve it <i>is</i> trivially relocatable if you let it allocate a sentinel n=
ode on the heap; but no vendor actually does that, AFAIK.=C2=A0 Somehow, it=
s (super obvious in hindsight) non-trivial relocatability never impinged on=
my consciousness until today.</div><div><br></div><div>There remains a cat=
egory of types =E2=80=94 such as a C++03-era-copy-only `shared_ptr` =E2=80=
=94 whose "moved-from" states are not "noop destructible&quo=
t; but=C2=A0which nevertheless are trivially relocatable.=C2=A0 However, I =
am kicking myself over the loss of std::list, std::map, and std::set.</div>=
<div><br></div><div>=E2=80=93Arthur</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" 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/CADvuK0LG4qKeRF4aGWC-8wG2z8-a19KPmOuf=
o_hjr-4HA23iZQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LG4qKeRF4a=
GWC-8wG2z8-a19KPmOufo_hjr-4HA23iZQ%40mail.gmail.com</a>.<br />
--000000000000ca00940571cd2db1--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Wed, 25 Jul 2018 01:30:44 -0700 (PDT)
Raw View
------=_Part_6092_689868245.1532507444812
Content-Type: multipart/alternative;
boundary="----=_Part_6093_541082282.1532507444812"
------=_Part_6093_541082282.1532507444812
Content-Type: text/plain; charset="UTF-8"
>
> How does one manage the lifetime of the exception_ptr object if std::error
>>> cannot call a non-trivial destructor on its final destruction?
>>>
>>
>> Compiler magic. `std::error` can do it because the standard *says* that
>> it can.
>>
>
> I think I misunderstood what you were saying. The answer is still
> "compiler magic", but a different form.
>
> If you're talking about the throwing of `std::error` as an exception and
> its propagation up the call graph, that is a function of the static
> exception machinery. This is conceptually based on return values and the
> like, but the compiler is intimately involved. Therefore, it can choose to
> call `std::error`'s non-trivial destructor or not, as it sees fit, in a
> static way. After all, if it's "copying" the object from the current stack
> to the caller's value, then it knows that it can just do a memcpy and not
> call the destructor. Or stick it in a register. And that's a static thing.
>
> Once the object materializes in a way you can inspect it, then it acts
> like a regular object. Copying it bumps the reference counter, if one
> exists. Destroying it decrements the reference counter if it exists. And
> the like.
>
> The important compiler magic for `std::error` is its treatment during
> exception propagation, which user code cannot impinge upon.
>
Ah, the "token exception throwing" model. I understand where you are at
now. In a similar place as Jacob, who wrote that counterproposal to mine in
that other thread.
I think Herb did everyone a disfavour by using the phrase "static
exceptions" in his paper. We need to dispense with that phrase, it is
unhelpful and confusing because it has meaning in the mind of the beholder.
I'll drop him a line there now and see if I can persuade him to revise his
paper with more clarifying terminology.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/e139f553-8279-4386-b136-5564a13df188%40isocpp.org.
------=_Part_6093_541082282.1532507444812
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<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"><blockquote c=
lass=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr"><div>How does one manage the lifetime of the exce=
ption_ptr object if std::error cannot call a non-trivial destructor on its =
final destruction?</div></div></blockquote><div><br></div><div>Compiler mag=
ic. `std::error` can do it because the standard <i>says</i> that it can.<br=
></div></div></blockquote><div><br></div><div>I think I misunderstood what =
you were saying. The answer is still "compiler magic", but a diff=
erent form.</div><div><br></div><div>If you're talking about the throwi=
ng of `std::error` as an exception and its propagation up the call graph, t=
hat is a function of the static exception machinery. This is conceptually b=
ased on return values and the like, but the compiler is intimately involved=
.. Therefore, it can choose to call `std::error`'s non-trivial destructo=
r or not, as it sees fit, in a static way. After all, if it's "cop=
ying" the object from the current stack to the caller's value, the=
n it knows that it can just do a memcpy and not call the destructor. Or sti=
ck it in a register. And that's a static thing.</div><div><br></div><di=
v>Once the object materializes in a way you can inspect it, then it acts li=
ke a regular object. Copying it bumps the reference counter, if one exists.=
Destroying it decrements the reference counter if it exists. And the like.=
</div><div><br></div><div>The important compiler magic for `std::error` is =
its treatment during exception propagation, which user code cannot impinge =
upon.<br></div></div></blockquote><div><br></div><div>Ah, the "token e=
xception throwing" model. I understand where you are at now. In a simi=
lar place as Jacob, who wrote that counterproposal to mine in that other th=
read.</div><div><br></div><div>I think Herb did everyone a disfavour by usi=
ng the phrase "static exceptions" in his paper. We need to dispen=
se with that phrase, it is unhelpful and confusing because it has meaning i=
n the mind of the beholder.</div><div><br></div><div>I'll drop him a li=
ne there now and see if I can persuade him to revise his paper with more cl=
arifying terminology.</div><div><br></div><div>Niall</div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/e139f553-8279-4386-b136-5564a13df188%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/e139f553-8279-4386-b136-5564a13df188=
%40isocpp.org</a>.<br />
------=_Part_6093_541082282.1532507444812--
------=_Part_6092_689868245.1532507444812--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Wed, 25 Jul 2018 01:53:02 -0700 (PDT)
Raw View
------=_Part_9583_205018147.1532508782816
Content-Type: multipart/alternative;
boundary="----=_Part_9584_1303861970.1532508782817"
------=_Part_9584_1303861970.1532508782817
Content-Type: text/plain; charset="UTF-8"
>
>
> Niall, could you elaborate a little on how relocatability is relevant to
> memory maps? (Bearing in mind that I don't know exactly what you mean by
> "memory map".)
>
> I can certainly imagine a chain of reasoning like this...
> (Niall is implementing afio) -> (Niall wants to use the new error-handling
> scheme) -> (the new error-handling scheme seems to require something like
> "trivially relocatable" to get the best performance) -> (Niall wants the
> best performance) -> (afio requires something like "trivially relocatable")
> ...but this chain is *very* weak and circumstantial, IMO. If there's
> something specific to the problem domain that involves "relocation," I'd
> like to know about it for my paper.
>
No, it's far more fundamental than that.
Mapped memory enables three new things:
1. Object lifetime can now exceed that of the program. This has obvious
difficulties wrt the current standard.
2. Objects can exist in multiple, concurrent instances of a C++ program.
The current standard assumes there can only be one C++ program.
3. The same object can have multiple addresses in a C++ program, and it
is a hard assumption in the current standard that this is impossible.
All three are highly problematic for the current C++ standard, and I make a
stab in the next revision of P1031 at proposing changes to the C++ object
model to handle these.
Trivial relocatability is utterly essential for mapped memory. Memory maps
can arbitrarily change address, whether due to capacity expansion, or due
to program restart. The objects stored within them therefore have a hard
requirement to be trivially relocatable. You will note that this "trivially
relocatable" is much stronger than your "trivially relocatable" because the
object cannot refer to state outside itself, like ordinary pointers. So I
am likely to invent a new name for it to avoid confusion, "trivially
persistable" is my current choice.
Now you might say "can't we run a fixup routine on them?" and the answer is
yes. But during Rapperswil I canvassed for opinions on this, and there was
widespread consensus that WG21 wants to see the fundamental proposal first,
and once that has been groked, then and only then do we start thinking
about fixup routines, and thereafter serialisation i.e. iostreams v2. Note
that fixup routines always work in place on the same memory, whereas
serialisation/deserialisation works by copy, so the proposed tiering would
be:
1. Trivially persistable objects.
2. Non-trivially persistable objects, which need explicit but entirely
compiler implemented in-place blessing and unblessing. For example,
anything with a vptr.
3. Non-trivially persitable objects with user customised routines to
implement the in-place blessing and unblessing.
4. Trivially serialisable objects (requires a copy) where the compiler
can use Reflection to deduce the right thing to do on its own.
5. Non-trivially serialisable objects (requires a copy) with user
customised routines.
Does it make sense now where relocatibility comes into P1031 *Low level
file i/o* now?
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c523f39e-8049-4ecd-b36a-879ee0c88cfa%40isocpp.org.
------=_Part_9584_1303861970.1532508782817
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<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>Niall, could you elaborate a little =
on how relocatability is relevant to memory maps? =C2=A0(Bearing in mind th=
at I don't know exactly what you mean by "memory map".)</div>=
<div><br></div><div>I can certainly imagine a chain of reasoning like this.=
...</div><div>(Niall is implementing afio) -> (Niall wants to use the new=
error-handling scheme) ->=C2=A0(the new error-handling scheme seems to =
require something like "trivially relocatable" to get the best pe=
rformance) -> (Niall wants the best performance) ->=C2=A0(afio requir=
es something like "trivially relocatable")<br></div><div>...but t=
his chain is <i>very</i> weak and circumstantial, IMO.=C2=A0 If there's=
something specific to the problem domain that involves "relocation,&q=
uot; I'd like to know about it for my paper.</div></div></div></div></b=
lockquote><div>=C2=A0</div><div>No, it's far more fundamental than that=
..</div><div><br></div><div>Mapped memory enables three new things:</div><di=
v><ol><li>Object lifetime can now exceed that of the program. This has obvi=
ous difficulties wrt the current standard.</li><li>Objects can exist in mul=
tiple, concurrent instances of a C++ program. The current standard assumes =
there can only be one C++ program.</li><li>The same object can have multipl=
e addresses in a C++ program, and it is a hard assumption in the current st=
andard that this is impossible.</li></ol><div>All three are highly problema=
tic for the current C++ standard, and I make a stab in the next revision of=
P1031 at proposing changes to the C++ object model to handle these.</div><=
/div><div><br></div><div>Trivial relocatability is utterly essential for ma=
pped memory. Memory maps can arbitrarily change address, whether due to cap=
acity expansion, or due to program restart. The objects stored within them =
therefore have a hard requirement to be trivially relocatable. You will not=
e that this "trivially relocatable" is much stronger than your &q=
uot;trivially relocatable" because the object cannot refer to state ou=
tside itself, like ordinary pointers. So I am likely to invent a new name f=
or it to avoid confusion, "trivially persistable" is my current c=
hoice.</div><div><br></div><div>Now you might say "can't we run a =
fixup routine on them?" and the answer is yes. But during Rapperswil I=
canvassed for opinions on this, and there was widespread consensus that WG=
21 wants to see the fundamental proposal first, and once that has been grok=
ed, then and only then do we start thinking about fixup routines, and there=
after serialisation i.e. iostreams v2. Note that fixup routines always work=
in place on the same memory, whereas serialisation/deserialisation works b=
y copy, so the proposed tiering would be:</div><div><ol><li>Trivially persi=
stable objects.</li><li>Non-trivially persistable objects, which need expli=
cit but entirely compiler implemented in-place blessing and unblessing. For=
example, anything with a vptr.</li><li>Non-trivially persitable objects wi=
th user customised routines to implement the in-place blessing and unblessi=
ng.</li><li>Trivially serialisable objects (requires a copy) where the comp=
iler can use Reflection to deduce the right thing to do on its own.</li><li=
>Non-trivially serialisable objects (requires a copy) with user customised =
routines.</li></ol><div>Does it make sense now where relocatibility comes i=
nto P1031 <i>Low level file i/o</i>=C2=A0now?</div></div><div><br></div><di=
v>Niall</div><div><br></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c523f39e-8049-4ecd-b36a-879ee0c88cfa%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c523f39e-8049-4ecd-b36a-879ee0c88cfa=
%40isocpp.org</a>.<br />
------=_Part_9584_1303861970.1532508782817--
------=_Part_9583_205018147.1532508782816--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Wed, 25 Jul 2018 02:21:31 -0700
Raw View
--0000000000007e89180571cf67ba
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wed, Jul 25, 2018 at 1:53 AM, Niall Douglas <nialldouglas14@gmail.com>
wrote:
>
>> Niall, could you elaborate a little on how relocatability is relevant to
>> memory maps? (Bearing in mind that I don't know exactly what you mean b=
y
>> "memory map".)
>>
>> I can certainly imagine a chain of reasoning like this...
>> (Niall is implementing afio) -> (Niall wants to use the new
>> error-handling scheme) -> (the new error-handling scheme seems to requir=
e
>> something like "trivially relocatable" to get the best performance) ->
>> (Niall wants the best performance) -> (afio requires something like
>> "trivially relocatable")
>> ...but this chain is *very* weak and circumstantial, IMO. If there's
>> something specific to the problem domain that involves "relocation," I'd
>> like to know about it for my paper.
>>
>
> No, it's far more fundamental than that.
>
> Mapped memory enables three new things:
>
> 1. Object lifetime can now exceed that of the program. This has
> obvious difficulties wrt the current standard.
> 2. Objects can exist in multiple, concurrent instances of a C++
> program. The current standard assumes there can only be one C++ progra=
m.
> 3. The same object can have multiple addresses in a C++ program, and
> it is a hard assumption in the current standard that this is impossibl=
e.
>
> All three are highly problematic for the current C++ standard, and I make
> a stab in the next revision of P1031 at proposing changes to the C++ obje=
ct
> model to handle these.
>
> Trivial relocatability is utterly essential for mapped memory. Memory map=
s
> can arbitrarily change address, whether due to capacity expansion, or due
> to program restart. The objects stored within them therefore have a hard
> requirement to be trivially relocatable. You will note that this "trivial=
ly
> relocatable" is much stronger than your "trivially relocatable" because t=
he
> object cannot refer to state outside itself, like ordinary pointers. So I
> am likely to invent a new name for it to avoid confusion, "trivially
> persistable" is my current choice.
>
I was worried it was something like that.
"""
P.S. =E2=80=94 Re naming, I do worry =E2=80=94 not about stepping on the EL=
F notion of
"relocations" =E2=80=94 but on the stuff done by e.g. Boost.Interprocess an=
d Bob
Steagall, where you can take a whole custom-allocated data structure based
at address 0xfoo and *share* the whole shebang (including all its pointers
and pointees) into a different process based at some other address 0xbar,
and still expect it to run correctly. This is the use-case for
boost::interprocess::offset_ptr, and could plausibly be described as a kind
of "relocation" (in the English-word sense). However,
boost::interprocess::offset_ptr (or any object recursively containing
offset_ptr) is the canonical example of a *non*-trivially-relocatable class
type in the P1029 and P1144 senses.
"""
I would suggest that data structures using offset_ptr could just be
described as "position-independent," in the sense that we already use that
term for "position-independent code" and "position-independent data."
P1144 builds up trivial relocatability as a property of the whole class
(because it depends on an interaction between the move-constructor and the
destructor).
Position-independence is an even more high-level property; it cannot be
built up class by class; it is an emergent property of the *entire data
structure*. For example, a struct containing members of type offset_ptr<T>
is definitely not trivially relocatable, and counts as
"position-independent" only if all those offset_ptrs point into the same
shared memory segment where the struct itself already lives. If any one of
those offset_ptrs points to global data, or points to the process's own
heap or stack, then the data structure will *not* be shareable between
different processes.
And vice versa: `std::list` is not trivially relocatable, but there's
nothing stopping you from putting a fancy std::list into a shared memory
segment; it'll work fine.
And vice versa again: having a vptr does not make an object
non-trivially-relocatable, but it does put quite a wrinkle in any attempt
to meaningfully "share" the object across a process boundary (since the guy
on the other side might not have a copy of the object's vtable).
Fortunately/unfortunately, the orthogonality of the two concepts means that
you can investigate "position-independence / shareability / persistability"
without having any formal way to talk about trivial relocatability. Having
trivial relocatability in the language will not get you any closer to
"position-independence / shareability / persistability."
Does it make sense now where relocatibility comes into P1031 *Low level
> file i/o* now?
>
I think I understand where the idea came from, but I think it's a wrong
idea.
=E2=80=93Arthur
--=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/CADvuK0LSd6t1TdnvMT0chCu55g5edoQEB%3D6Srzyqk9oaD=
NMW1A%40mail.gmail.com.
--0000000000007e89180571cf67ba
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wed, Jul 25, 2018 at 1:53 AM, Niall Douglas <span dir=
=3D"ltr"><<a href=3D"mailto:nialldouglas14@gmail.com" target=3D"_blank">=
nialldouglas14@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra=
"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-=
left-color:rgb(204,204,204);padding-left:1ex"><span class=3D"gmail-"><block=
quote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-w=
idth:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding=
-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><br></div>=
<div>Niall, could you elaborate a little on how relocatability is relevant =
to memory maps? =C2=A0(Bearing in mind that I don't know exactly what y=
ou mean by "memory map".)</div><div><br></div><div>I can certainl=
y imagine a chain of reasoning like this...</div><div>(Niall is implementin=
g afio) -> (Niall wants to use the new error-handling scheme) ->=C2=
=A0(the new error-handling scheme seems to require something like "tri=
vially relocatable" to get the best performance) -> (Niall wants th=
e best performance) ->=C2=A0(afio requires something like "triviall=
y relocatable")<br></div><div>...but this chain is <i>very</i> weak an=
d circumstantial, IMO.=C2=A0 If there's something specific to the probl=
em domain that involves "relocation," I'd like to know about =
it for my paper.</div></div></div></div></blockquote><div>=C2=A0</div></spa=
n><div>No, it's far more fundamental than that.</div><div><br></div><di=
v>Mapped memory enables three new things:</div><div><ol><li>Object lifetime=
can now exceed that of the program. This has obvious difficulties wrt the =
current standard.</li><li>Objects can exist in multiple, concurrent instanc=
es of a C++ program. The current standard assumes there can only be one C++=
program.</li><li>The same object can have multiple addresses in a C++ prog=
ram, and it is a hard assumption in the current standard that this is impos=
sible.</li></ol><div>All three are highly problematic for the current C++ s=
tandard, and I make a stab in the next revision of P1031 at proposing chang=
es to the C++ object model to handle these.</div></div><div><br></div><div>=
Trivial relocatability is utterly essential for mapped memory. Memory maps =
can arbitrarily change address, whether due to capacity expansion, or due t=
o program restart. The objects stored within them therefore have a hard req=
uirement to be trivially relocatable. You will note that this "trivial=
ly relocatable" is much stronger than your "trivially relocatable=
" because the object cannot refer to state outside itself, like ordina=
ry pointers. So I am likely to invent a new name for it to avoid confusion,=
"trivially persistable" is my current choice.</div></blockquote>=
<div><br></div><div>I was worried it was something like that.</div><div><br=
></div><div>"""</div><div><span style=3D"font-size:12.800000=
190734863px">P.S. =E2=80=94 Re naming, I do worry =E2=80=94 not about stepp=
ing on the ELF notion of "relocations" =E2=80=94 but on the stuff=
done by e.g. Boost.Interprocess and Bob Steagall, where you can take a who=
le custom-allocated data structure based at address 0xfoo and=C2=A0</span><=
i style=3D"font-size:12.800000190734863px">share</i><span style=3D"font-siz=
e:12.800000190734863px">=C2=A0the whole shebang (including all its pointers=
and pointees) into a different process based at some other address 0xbar, =
and still expect it to run correctly.=C2=A0 This is the use-case for boost:=
:interprocess::offset_</span><wbr style=3D"font-size:12.800000190734863px">=
<span style=3D"font-size:12.800000190734863px">ptr, and could plausibly be =
described as a kind of "relocation" (in the English-word sense).=
=C2=A0 However, boost::interprocess::offset_</span><wbr style=3D"font-size:=
12.800000190734863px"><span style=3D"font-size:12.800000190734863px">ptr (o=
r any object recursively containing offset_ptr) is the canonical example of=
a=C2=A0</span><i style=3D"font-size:12.800000190734863px"><b>non</b></i><s=
pan style=3D"font-size:12.800000190734863px">-trivially-relocatable class t=
ype in the P1029 and P1144 senses.</span><br></div><div>"""<=
/div><div><br></div><div>I would suggest that data structures using offset_=
ptr could just be described as "position-independent," in the sen=
se that we already use that term for "position-independent code" =
and "position-independent data."</div><div><br></div><div>P1144 b=
uilds up trivial relocatability as a property of the whole class (because i=
t depends on an interaction between the move-constructor and the destructor=
).</div><div><br></div><div>Position-independence is an even more high-leve=
l property; it cannot be built up class by class; it is an emergent propert=
y of the <i>entire data structure</i>.=C2=A0 For example, a struct containi=
ng members of type offset_ptr<T> is definitely not trivially relocata=
ble, and counts as "position-independent" only if all those offse=
t_ptrs point into the same shared memory segment where the struct itself al=
ready lives. If any one of those offset_ptrs points to global data, or poin=
ts to the process's own heap or stack, then the data structure will <i>=
not</i> be shareable between different processes.</div><div><br></div><div>=
And vice versa: `std::list` is not trivially relocatable, but there's n=
othing stopping you from putting a fancy std::list into a shared memory seg=
ment; it'll work fine.</div><div><br></div><div>And vice versa again: h=
aving a vptr does not make an object non-trivially-relocatable, but it does=
put quite a wrinkle in any attempt to meaningfully "share" the o=
bject across a process boundary (since the guy on the other side might not =
have a copy of the object's vtable).</div><div><br></div><div>Fortunate=
ly/unfortunately, the orthogonality of the two concepts means that you can =
investigate "position-independence / shareability / persistability&quo=
t; without having any formal way to talk about trivial relocatability. Havi=
ng trivial relocatability in the language will not get you any closer to &q=
uot;position-independence / shareability / persistability."</div><div>=
<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8=
ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,=
204,204);padding-left:1ex"><div><div>Does it make sense now where relocatib=
ility comes into P1031 <i>Low level file i/o</i>=C2=A0now?</div></div></blo=
ckquote><div><br></div><div>I think I understand where the idea came from, =
but I think it's a wrong idea.</div><div><br></div><div>=E2=80=93Arthur=
</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" 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/CADvuK0LSd6t1TdnvMT0chCu55g5edoQEB%3D=
6Srzyqk9oaDNMW1A%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0LSd6t1Td=
nvMT0chCu55g5edoQEB%3D6Srzyqk9oaDNMW1A%40mail.gmail.com</a>.<br />
--0000000000007e89180571cf67ba--
.
Author: mihailnajdenov@gmail.com
Date: Wed, 25 Jul 2018 09:44:01 -0700 (PDT)
Raw View
------=_Part_116_971667955.1532537041868
Content-Type: multipart/alternative;
boundary="----=_Part_117_963310451.1532537041869"
------=_Part_117_963310451.1532537041869
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wednesday, July 25, 2018 at 9:42:15 AM UTC+3, Arthur O'Dwyer wrote:
>
> On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <jmck...@gmail.com=20
> <javascript:>> wrote:
>
>> On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@gmail.com wrote=
:
>>>
>>> On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>>>>
>>>> But as Arthur noted, this definition would exempt an entire category o=
f=20
>>>> objects like `std::list`, where move does not leave them in a "trivial=
"=20
>>>> state. The P1144 definition of relocation is that "move+destroy" is=20
>>>> equivalent to "memcpy+drop". That's not the same thing as declaring th=
at=20
>>>> movement leaves the object in a "trivial state".
>>>>
>>> =20
>>> I see, so 1144 "works" even if after 'move', the object needs to be=20
>>> non-trivially destroyed. Yeah, my observations do not apply then.
>>>
>>> [...]
>>>
>>
>> But you're right, that it should talk about cases like `std::list`. And=
=20
>> I'm rather surprised that it didn't bring them up.
>>
>
> Well, here's some revolting news: `std::list` *is not* trivially=20
> relocatable on any vendor today! I have just added a new subsection to=
=20
> Appendix C, giving `std::list` alongside my other examples of=20
> non-trivially-relocatable types:
>
> =3D=3D=3D=3D=3D
> std::list needs somewhere to store its "past-the-end" node, commonly=20
> referred to as the "sentinel node." If the sentinel node is allocated on=
=20
> the heap, then std::list can be trivially relocatable; but if the sentine=
l=20
> node is placed within the list object itself (as happens on libc++ and=20
> libstdc++), then relocating the list object will necessitate fixing up a=
=20
> pair of pointers elsewhere on the heap. This fixup cannot be simulated by=
=20
> memcpy.
>
But this is easily fixable by the implementation, no? They just need to=20
make the node (inline?) static and point to it instead. Could there be a=20
problem all lists having the same sentinel? =20
=20
>
> Traditional implementations of std::set and std::map also store a=20
> "past-the-end" node inside themselves and thus also fall into this catego=
ry.
>
> struct node {
> node *prev_ =3D nullptr;
> node *next_ =3D nullptr;
> };
> struct list {
> node n_;
> iterator begin() { return iterator(n_.next_); }
> iterator end() { return iterator(&n_); }
> list(list&& l) {
> if (l.n_.next_) l.n_.next_->prev_ =3D &n_; // fixup
> if (l.n_.prev_) l.n_.prev_->next_ =3D &n_; // fixup
> n_ =3D l.n_;
> l.n_ =3D node{};
> }
> // ...
> };
> =3D=3D=3D=3D=3D
>
> Anyone got any thoughts on std::list? I'm shocked (in a=20
> "why-didn't-you-do-my-homework-for-me" way ;)) that the non-trivial=20
> relocatability of `list`, `set`, map`, etc. wasn't raised in any previous=
=20
> papers or mailing-list discussions on the topic. Indeed, we've kind of be=
en=20
> using `list` as a poster child for relocatability. And I believe it *is*=
=20
> trivially relocatable if you let it allocate a sentinel node on the heap;=
=20
> but no vendor actually does that, AFAIK. Somehow, its (super obvious in=
=20
> hindsight) non-trivial relocatability never impinged on my consciousness=
=20
> until today.
>
> There remains a category of types =E2=80=94 such as a C++03-era-copy-only=
=20
> `shared_ptr` =E2=80=94 whose "moved-from" states are not "noop destructib=
le"=20
> but which nevertheless are trivially relocatable. However, I am kicking=
=20
> myself over the loss of std::list, std::map, and std::set.
>
> =E2=80=93Arthur
>
--=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/ad1646fa-a0ea-4413-83b3-1b84df57fef3%40isocpp.or=
g.
------=_Part_117_963310451.1532537041869
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, July 25, 2018 at 9:42:15 AM UTC+3, A=
rthur O'Dwyer wrote:<blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr">On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <span dir=3D"ltr">&=
lt;<a onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;" href=3D"javascript:" t=
arget=3D"_blank" rel=3D"nofollow" gdf-obfuscated-mailto=3D"_IsptC9hDwAJ">jm=
ck...@gmail.com</a>></span> wrote:<br><div><div class=3D"gmail_quote"><b=
lockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-le=
ft-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);pad=
ding-left:1ex"><div dir=3D"ltr"><div><div>On Monday, July 23, 2018 at 3:00:=
55 PM UTC-4, <a>mihailn...@gmail.com</a> wrote:<blockquote class=3D"gmail_q=
uote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-s=
tyle:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D=
"ltr">On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:<bloc=
kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-=
width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);paddin=
g-left:1ex"><div dir=3D"ltr"><div></div><div>But as Arthur noted, this defi=
nition would exempt an entire category of objects like `std::list`, where m=
ove does not leave them in a "trivial" state. The P1144 definitio=
n of relocation is that "move+destroy" is equivalent to "mem=
cpy+drop". That's not the same thing as declaring that movement le=
aves the object in a "trivial state".<br></div></div></blockquote=
><div>=C2=A0</div><div>I see, so 1144 "works" even if after '=
move', the object needs to be non-trivially destroyed. Yeah, my observa=
tions do not apply then.</div><div><br></div><div>[...]</div></div></blockq=
uote></div></div><div><br></div><div>But you're right, that it should t=
alk about cases like `std::list`. And I'm rather surprised that it didn=
't bring them up.</div></div></blockquote><div><br></div><div>Well, her=
e's some revolting news: `std::list` <i><b>is not</b></i> trivially rel=
ocatable on any vendor today!=C2=A0=C2=A0I have just added a new subsection=
to Appendix C, giving `std::list` alongside my other examples of non-trivi=
ally-relocatable types:</div><div><br></div><div>=3D=3D=3D=3D=3D</div><div>=
<div>std::list needs somewhere to store its "past-the-end" node, =
commonly referred to as the "sentinel node." If the sentinel node=
is allocated on the heap, then std::list can be trivially relocatable; but=
if the sentinel node is placed within the list object itself (as happens o=
n libc++ and libstdc++), then relocating the list object will necessitate f=
ixing up a pair of pointers elsewhere on the heap. This fixup cannot be sim=
ulated by memcpy.</div></div></div></div></div></blockquote><div><br></div>=
<div>But this is easily fixable by the implementation, no? They just need t=
o make the node (inline?) static and point to it instead. Could there be a =
problem all lists having the same sentinel? =C2=A0</div><div>=C2=A0</div><b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=
=3D"gmail_quote"><div><div><br></div><div>Traditional implementations of st=
d::set and std::map also store a "past-the-end" node inside thems=
elves and thus also fall into this category.</div><div><br></div><div>=C2=
=A0struct node {</div><div>=C2=A0 =C2=A0 node *prev_ =3D nullptr;</div><div=
>=C2=A0 =C2=A0 node *next_ =3D nullptr;</div><div>};</div><div>struct list =
{</div><div>=C2=A0 =C2=A0 node n_;</div><div>=C2=A0 =C2=A0 iterator begin()=
{ return iterator(n_.next_); }</div><div>=C2=A0 =C2=A0 iterator end() { re=
turn iterator(&n_); }</div><div>=C2=A0 =C2=A0 list(list&& l) {<=
/div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (l.n_.next_) l.n_.next_->prev_ =
=3D &n_; =C2=A0// fixup</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (l.n_.=
prev_) l.n_.prev_->next_ =3D &n_; =C2=A0// fixup</div><div>=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 n_ =3D l.n_;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 l.n=
_ =3D node{};</div><div>=C2=A0 =C2=A0 }</div><div>=C2=A0 =C2=A0 // ...</div=
><div>};</div></div><div>=3D=3D=3D=3D=3D</div><div><br></div><div>Anyone go=
t any thoughts on std::list?=C2=A0 I'm shocked (in a "why-didn'=
;t-you-do-my-<wbr>homework-for-me" way ;)) that the non-trivial reloca=
tability of `list`, `set`, map`, etc. wasn't raised in any previous pap=
ers or mailing-list discussions on the topic. Indeed, we've kind of bee=
n using `list` as a poster child for relocatability. And I believe it <i>is=
</i> trivially relocatable if you let it allocate a sentinel node on the he=
ap; but no vendor actually does that, AFAIK.=C2=A0 Somehow, its (super obvi=
ous in hindsight) non-trivial relocatability never impinged on my conscious=
ness until today.</div><div><br></div><div>There remains a category of type=
s =E2=80=94 such as a C++03-era-copy-only `shared_ptr` =E2=80=94 whose &quo=
t;moved-from" states are not "noop destructible" but=C2=A0wh=
ich nevertheless are trivially relocatable.=C2=A0 However, I am kicking mys=
elf over the loss of std::list, std::map, and std::set.</div><div><br></div=
><div>=E2=80=93Arthur</div></div></div></div>
</blockquote></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ad1646fa-a0ea-4413-83b3-1b84df57fef3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ad1646fa-a0ea-4413-83b3-1b84df57fef3=
%40isocpp.org</a>.<br />
------=_Part_117_963310451.1532537041869--
------=_Part_116_971667955.1532537041868--
.
Author: =?UTF-8?B?R2HFoXBlciBBxb5tYW4=?= <gasper.azman@gmail.com>
Date: Wed, 25 Jul 2018 18:15:24 +0100
Raw View
--00000000000070b5930571d607c8
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wed, Jul 25, 2018 at 5:44 PM, <mihailnajdenov@gmail.com> wrote:
>
>
> On Wednesday, July 25, 2018 at 9:42:15 AM UTC+3, Arthur O'Dwyer wrote:
>>
>> On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>
>>> On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@gmail.com
>>> wrote:
>>>>
>>>> On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>>>>>
>>>>> But as Arthur noted, this definition would exempt an entire category
>>>>> of objects like `std::list`, where move does not leave them in a "tri=
vial"
>>>>> state. The P1144 definition of relocation is that "move+destroy" is
>>>>> equivalent to "memcpy+drop". That's not the same thing as declaring t=
hat
>>>>> movement leaves the object in a "trivial state".
>>>>>
>>>>
>>>> I see, so 1144 "works" even if after 'move', the object needs to be
>>>> non-trivially destroyed. Yeah, my observations do not apply then.
>>>>
>>>> [...]
>>>>
>>>
>>> But you're right, that it should talk about cases like `std::list`. And
>>> I'm rather surprised that it didn't bring them up.
>>>
>>
>> Well, here's some revolting news: `std::list` *is not* trivially
>> relocatable on any vendor today! I have just added a new subsection to
>> Appendix C, giving `std::list` alongside my other examples of
>> non-trivially-relocatable types:
>>
>> =3D=3D=3D=3D=3D
>> std::list needs somewhere to store its "past-the-end" node, commonly
>> referred to as the "sentinel node." If the sentinel node is allocated on
>> the heap, then std::list can be trivially relocatable; but if the sentin=
el
>> node is placed within the list object itself (as happens on libc++ and
>> libstdc++), then relocating the list object will necessitate fixing up a
>> pair of pointers elsewhere on the heap. This fixup cannot be simulated b=
y
>> memcpy.
>>
>
> But this is easily fixable by the implementation, no? They just need to
> make the node (inline?) static and point to it instead. Could there be a
> problem all lists having the same sentinel?
>
It's a doubly-linked list. You either have a branch in every iterator to
check whether you're at a sentinel and then *do something else* to
implement -- for the sentinel node, or have a different sentinel that looks
like a normal node and just look at the pointer :).
>
>
>>
>> Traditional implementations of std::set and std::map also store a
>> "past-the-end" node inside themselves and thus also fall into this categ=
ory.
>>
>> struct node {
>> node *prev_ =3D nullptr;
>> node *next_ =3D nullptr;
>> };
>> struct list {
>> node n_;
>> iterator begin() { return iterator(n_.next_); }
>> iterator end() { return iterator(&n_); }
>> list(list&& l) {
>> if (l.n_.next_) l.n_.next_->prev_ =3D &n_; // fixup
>> if (l.n_.prev_) l.n_.prev_->next_ =3D &n_; // fixup
>> n_ =3D l.n_;
>> l.n_ =3D node{};
>> }
>> // ...
>> };
>> =3D=3D=3D=3D=3D
>>
>> Anyone got any thoughts on std::list? I'm shocked (in a
>> "why-didn't-you-do-my-homework-for-me" way ;)) that the non-trivial
>> relocatability of `list`, `set`, map`, etc. wasn't raised in any previou=
s
>> papers or mailing-list discussions on the topic. Indeed, we've kind of b=
een
>> using `list` as a poster child for relocatability. And I believe it *is*
>> trivially relocatable if you let it allocate a sentinel node on the heap=
;
>> but no vendor actually does that, AFAIK. Somehow, its (super obvious in
>> hindsight) non-trivial relocatability never impinged on my consciousness
>> until today.
>>
>> There remains a category of types =E2=80=94 such as a C++03-era-copy-onl=
y
>> `shared_ptr` =E2=80=94 whose "moved-from" states are not "noop destructi=
ble"
>> but which nevertheless are trivially relocatable. However, I am kicking
>> myself over the loss of std::list, std::map, and std::set.
>>
>> =E2=80=93Arthur
>>
> --
> You received this message because you are subscribed to the Google Groups
> "ISO C++ Standard - Future Proposals" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to std-proposals+unsubscribe@isocpp.org.
> To post to this group, send email to std-proposals@isocpp.org.
> To view this discussion on the web visit https://groups.google.com/a/
> isocpp.org/d/msgid/std-proposals/ad1646fa-a0ea-4413-
> 83b3-1b84df57fef3%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/ad1646fa-a0=
ea-4413-83b3-1b84df57fef3%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=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/CAANG%3DkVwvJ4w-eCR%2BSyFn5kKHoAeeT1CifSZ6oJAFiJ=
nNQY8Vw%40mail.gmail.com.
--00000000000070b5930571d607c8
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Wed, Jul 25, 2018 at 5:44 PM, <span dir=3D"ltr"><<a href=3D"mail=
to:mihailnajdenov@gmail.com" target=3D"_blank">mihailnajdenov@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:1ex"><div dir=3D"ltr"><br><=
br>On Wednesday, July 25, 2018 at 9:42:15 AM UTC+3, Arthur O'Dwyer wrot=
e:<span class=3D""><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"=
>On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <span dir=3D"ltr"><<a rel=
=3D"nofollow">jmck...@gmail.com</a>></span> wrote:<br><div><div class=3D=
"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px=
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(=
204,204,204);padding-left:1ex"><div dir=3D"ltr"><div><div>On Monday, July 2=
3, 2018 at 3:00:55 PM UTC-4, <a>mihailn...@gmail.com</a> wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1=
px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:=
1ex"><div dir=3D"ltr">On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol B=
olas wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.=
8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204=
,204,204);padding-left:1ex"><div dir=3D"ltr"><div></div><div>But as Arthur =
noted, this definition would exempt an entire category of objects like `std=
::list`, where move does not leave them in a "trivial" state. The=
P1144 definition of relocation is that "move+destroy" is equival=
ent to "memcpy+drop". That's not the same thing as declaring =
that movement leaves the object in a "trivial state".<br></div></=
div></blockquote><div>=C2=A0</div><div>I see, so 1144 "works" eve=
n if after 'move', the object needs to be non-trivially destroyed. =
Yeah, my observations do not apply then.</div><div><br></div><div>[...]</di=
v></div></blockquote></div></div><div><br></div><div>But you're right, =
that it should talk about cases like `std::list`. And I'm rather surpri=
sed that it didn't bring them up.</div></div></blockquote><div><br></di=
v><div>Well, here's some revolting news: `std::list` <i><b>is not</b></=
i> trivially relocatable on any vendor today!=C2=A0=C2=A0I have just added =
a new subsection to Appendix C, giving `std::list` alongside my other examp=
les of non-trivially-relocatable types:</div><div><br></div><div>=3D=3D=3D=
=3D=3D</div><div><div>std::list needs somewhere to store its "past-the=
-end" node, commonly referred to as the "sentinel node." If =
the sentinel node is allocated on the heap, then std::list can be trivially=
relocatable; but if the sentinel node is placed within the list object its=
elf (as happens on libc++ and libstdc++), then relocating the list object w=
ill necessitate fixing up a pair of pointers elsewhere on the heap. This fi=
xup cannot be simulated by memcpy.</div></div></div></div></div></blockquot=
e><div><br></div></span><div>But this is easily fixable by the implementati=
on, no? They just need to make the node (inline?) static and point to it in=
stead. Could there be a problem all lists having the same sentinel? =C2=A0<=
/div></div></blockquote><div><br></div><div>It's a doubly-linked list. =
You either have a branch in every iterator to check whether you're at a=
sentinel and then *do something else* to implement -- for the sentinel nod=
e, or have a different sentinel that looks like a normal node and just look=
at the pointer :).</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"><d=
iv dir=3D"ltr"><span class=3D""><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padd=
ing-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div><div><b=
r></div><div>Traditional implementations of std::set and std::map also stor=
e a "past-the-end" node inside themselves and thus also fall into=
this category.</div><div><br></div><div>=C2=A0struct node {</div><div>=C2=
=A0 =C2=A0 node *prev_ =3D nullptr;</div><div>=C2=A0 =C2=A0 node *next_ =3D=
nullptr;</div><div>};</div><div>struct list {</div><div>=C2=A0 =C2=A0 node=
n_;</div><div>=C2=A0 =C2=A0 iterator begin() { return iterator(n_.next_); =
}</div><div>=C2=A0 =C2=A0 iterator end() { return iterator(&n_); }</div=
><div>=C2=A0 =C2=A0 list(list&& l) {</div><div>=C2=A0 =C2=A0 =C2=A0=
=C2=A0 if (l.n_.next_) l.n_.next_->prev_ =3D &n_; =C2=A0// fixup</d=
iv><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (l.n_.prev_) l.n_.prev_->next_ =
=3D &n_; =C2=A0// fixup</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 n_ =3D l.=
n_;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 l.n_ =3D node{};</div><div>=C2=A0=
=C2=A0 }</div><div>=C2=A0 =C2=A0 // ...</div><div>};</div></div><div>=3D=
=3D=3D=3D=3D</div><div><br></div><div>Anyone got any thoughts on std::list?=
=C2=A0 I'm shocked (in a "why-didn't-you-do-my-homework<wbr>-f=
or-me" way ;)) that the non-trivial relocatability of `list`, `set`, m=
ap`, etc. wasn't raised in any previous papers or mailing-list discussi=
ons on the topic. Indeed, we've kind of been using `list` as a poster c=
hild for relocatability. And I believe it <i>is</i> trivially relocatable i=
f you let it allocate a sentinel node on the heap; but no vendor actually d=
oes that, AFAIK.=C2=A0 Somehow, its (super obvious in hindsight) non-trivia=
l relocatability never impinged on my consciousness until today.</div><div>=
<br></div><div>There remains a category of types =E2=80=94 such as a C++03-=
era-copy-only `shared_ptr` =E2=80=94 whose "moved-from" states ar=
e not "noop destructible" but=C2=A0which nevertheless are trivial=
ly relocatable.=C2=A0 However, I am kicking myself over the loss of std::li=
st, std::map, and std::set.</div><div><br></div><div>=E2=80=93Arthur</div><=
/div></div></div>
</blockquote></span></div><span class=3D"">
<p></p>
-- <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@<wbr>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></span>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/ad1646fa-a0ea-4413-83b3-1b84df57fef3%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/ad16=
46fa-a0ea-4413-<wbr>83b3-1b84df57fef3%40isocpp.org</a><wbr>.<br>
</blockquote></div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAANG%3DkVwvJ4w-eCR%2BSyFn5kKHoAeeT1C=
ifSZ6oJAFiJnNQY8Vw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAANG%3DkVwvJ=
4w-eCR%2BSyFn5kKHoAeeT1CifSZ6oJAFiJnNQY8Vw%40mail.gmail.com</a>.<br />
--00000000000070b5930571d607c8--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Wed, 25 Jul 2018 10:34:28 -0700 (PDT)
Raw View
------=_Part_345_1618688643.1532540068412
Content-Type: multipart/alternative;
boundary="----=_Part_346_1278560248.1532540068413"
------=_Part_346_1278560248.1532540068413
Content-Type: text/plain; charset="UTF-8"
On Wednesday, July 25, 2018 at 4:30:44 AM UTC-4, Niall Douglas wrote:
>
> How does one manage the lifetime of the exception_ptr object if std::error
>>>> cannot call a non-trivial destructor on its final destruction?
>>>>
>>>
>>> Compiler magic. `std::error` can do it because the standard *says* that
>>> it can.
>>>
>>
>> I think I misunderstood what you were saying. The answer is still
>> "compiler magic", but a different form.
>>
>> If you're talking about the throwing of `std::error` as an exception and
>> its propagation up the call graph, that is a function of the static
>> exception machinery. This is conceptually based on return values and the
>> like, but the compiler is intimately involved. Therefore, it can choose to
>> call `std::error`'s non-trivial destructor or not, as it sees fit, in a
>> static way. After all, if it's "copying" the object from the current stack
>> to the caller's value, then it knows that it can just do a memcpy and not
>> call the destructor. Or stick it in a register. And that's a static thing.
>>
>> Once the object materializes in a way you can inspect it, then it acts
>> like a regular object. Copying it bumps the reference counter, if one
>> exists. Destroying it decrements the reference counter if it exists. And
>> the like.
>>
>> The important compiler magic for `std::error` is its treatment during
>> exception propagation, which user code cannot impinge upon.
>>
>
> Ah, the "token exception throwing" model. I understand where you are at
> now. In a similar place as Jacob, who wrote that counterproposal to mine in
> that other thread.
>
> I think Herb did everyone a disfavour by using the phrase "static
> exceptions" in his paper. We need to dispense with that phrase, it is
> unhelpful and confusing because it has meaning in the mind of the beholder.
>
> I'll drop him a line there now and see if I can persuade him to revise his
> paper with more clarifying terminology.
>
I may be wrong, but I think that you've misattributed the goals of P0709. I
think Herb used the phrase "static exceptions" because it gives the
*intended* impression. And I'm not sure that "deterministic exceptions"
would give a better impression.
"Static exceptions" tells you exactly what design P0709 outlines:
exceptions, without the dynamic nature of them. Catches catch by the exact
value thrown. Avenues of transmission from source to target is a static
property of the executable. And so forth.
That is, P0709 is exception handling with better performance. That is its
principle design.
While P0709 does spell out the mechanism of transmission, it doesn't
require that specific implementation. Table-based implementations are still
*allowed*; they're just not de-facto mandatory. And table-based
transmission can't happen across ABI boundaries. But if the compiler can
see all the code from throw to catch, then it can build an optimized static
table for handling it.
Or not, as it so chooses.
You can see this design further in that P0709 mandates that
`uncaught_exceptions` will still work, regardless of whether the exception
passing through is static or dynamic. This means that things like
`std::scope_fail` will work without changes.
Now, it may not be possible to do that for overhead-related reasons. But if
it's not possible, then the eventual more fleshed out static exception
design will have to provide *some *mechanism for telling the difference
between an object being destroyed due to static exception unwinding and
being destroyed due to normal local returns. That's an important aspect to
exceptions, so it's an important aspect to "static exceptions".
Similarly, one of the main reasons P0709 is fixed to using `std::error` as
its static exception type is that this permits all static exception
functions to transmit dynamic exceptions too. So if the receiver and sender
are dynamic, then calling the sender through some static exception function
won't break dynamic exceptions. Ensuring this is part-and-parcel of being a
design for an exception system.
By contrast, your view seems to be that "deterministic exceptions" are,
first and foremost, a C design with some C++ syntactic sugar that looks
suspiciously like C++'s exception mechanism. That is, it is not a priority
in your design that `_Fails()` based code behaves like exceptions. So would
your design provide a way to tell if an object is being destroyed due to an
exception?
By allowing `_Fails()` to provide types incompatible with `std::error`, you
also allow such code to impede the flow of dynamic exceptions. That's not a
priority for your design.
But it is a priority for P0709.
This seems to be a fundamental divergence of vision. You seem to want the C
mechanism dressed up in C++ clothing; P0709 seems to want exceptions
without the overhead.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c06a680b-08b1-409b-90ba-1625b7ae8b10%40isocpp.org.
------=_Part_346_1278560248.1532540068413
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Wednesday, July 25, 2018 at 4:30:44 AM UTC-4, Niall Dou=
glas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left=
: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><blockquote class=
=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" s=
tyle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:=
1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;m=
argin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr"><div>How does one manage the lifetime of the exception_ptr object if st=
d::error cannot call a non-trivial destructor on its final destruction?</di=
v></div></blockquote><div><br></div><div>Compiler magic. `std::error` can d=
o it because the standard <i>says</i> that it can.<br></div></div></blockqu=
ote><div><br></div><div>I think I misunderstood what you were saying. The a=
nswer is still "compiler magic", but a different form.</div><div>=
<br></div><div>If you're talking about the throwing of `std::error` as =
an exception and its propagation up the call graph, that is a function of t=
he static exception machinery. This is conceptually based on return values =
and the like, but the compiler is intimately involved. Therefore, it can ch=
oose to call `std::error`'s non-trivial destructor or not, as it sees f=
it, in a static way. After all, if it's "copying" the object =
from the current stack to the caller's value, then it knows that it can=
just do a memcpy and not call the destructor. Or stick it in a register. A=
nd that's a static thing.</div><div><br></div><div>Once the object mate=
rializes in a way you can inspect it, then it acts like a regular object. C=
opying it bumps the reference counter, if one exists. Destroying it decreme=
nts the reference counter if it exists. And the like.</div><div><br></div><=
div>The important compiler magic for `std::error` is its treatment during e=
xception propagation, which user code cannot impinge upon.<br></div></div><=
/blockquote><div><br></div><div>Ah, the "token exception throwing"=
; model. I understand where you are at now. In a similar place as Jacob, wh=
o wrote that counterproposal to mine in that other thread.</div><div><br></=
div><div>I think Herb did everyone a disfavour by using the phrase "st=
atic exceptions" in his paper. We need to dispense with that phrase, i=
t is unhelpful and confusing because it has meaning in the mind of the beho=
lder.</div><div><br></div><div>I'll drop him a line there now and see i=
f I can persuade him to revise his paper with more clarifying terminology.<=
/div></blockquote><div><br></div><div>I may be wrong, but I think that you&=
#39;ve misattributed the goals of P0709. I think Herb used the phrase "=
;static exceptions" because it gives the <i>intended</i> impression. A=
nd I'm not sure that "deterministic exceptions" would give a =
better impression.</div><div><br></div><div>"Static exceptions" t=
ells you exactly what design P0709 outlines: exceptions, without the dynami=
c nature of them. Catches catch by the exact value thrown. Avenues of trans=
mission from source to target is a static property of the executable. And s=
o forth.</div><div><br></div><div>That is, P0709 is exception handling with=
better performance. That is its principle design.</div><div><br></div><div=
>While P0709 does spell out the mechanism of transmission, it doesn't r=
equire that specific implementation. Table-based implementations are still =
<i>allowed</i>; they're just not de-facto mandatory. And table-based tr=
ansmission can't happen across ABI boundaries. But if the compiler can =
see all the code from throw to catch, then it can build an optimized static=
table for handling it.</div><div><br></div><div>Or not, as it so chooses.<=
/div><div><br></div><div>You can see this design further in that P0709 mand=
ates that `uncaught_exceptions` will still work, regardless of whether the =
exception passing through is static or dynamic. This means that things like=
`std::scope_fail` will work without changes.</div><div><br></div><div>Now,=
it may not be possible to do that for overhead-related reasons. But if it&=
#39;s not possible, then the eventual more fleshed out static exception des=
ign will have to provide <i>some </i>mechanism for telling the difference b=
etween an object being destroyed due to static exception unwinding and bein=
g destroyed due to normal local returns. That's an important aspect to =
exceptions, so it's an important aspect to "static exceptions"=
;.</div><div><br></div><div>Similarly, one of the main reasons P0709 is fix=
ed to using `std::error` as its static exception type is that this permits =
all static exception functions to transmit dynamic exceptions too. So if th=
e receiver and sender are dynamic, then calling the sender through some sta=
tic exception function won't break dynamic exceptions. Ensuring this is=
part-and-parcel of being a design for an exception system.<br></div><div><=
br></div><div>By contrast, your view seems to be that "deterministic e=
xceptions" are, first and foremost, a C design with some C++ syntactic=
sugar that looks suspiciously like C++'s exception mechanism. That is,=
it is not a priority in your design that `_Fails()` based code behaves lik=
e exceptions. So would your design provide a way to tell if an object is be=
ing destroyed due to an exception?</div><div><br></div><div>By allowing `_F=
ails()` to provide types incompatible with `std::error`, you also allow suc=
h code to impede the flow of dynamic exceptions. That's not a priority =
for your design.</div><div><br></div><div>But it is a priority for P0709.<b=
r></div><div><br></div><div>This seems to be a fundamental divergence of vi=
sion. You seem to want the C mechanism dressed up in C++ clothing; P0709 se=
ems to want exceptions without the overhead.<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/c06a680b-08b1-409b-90ba-1625b7ae8b10%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c06a680b-08b1-409b-90ba-1625b7ae8b10=
%40isocpp.org</a>.<br />
------=_Part_346_1278560248.1532540068413--
------=_Part_345_1618688643.1532540068412--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 25 Jul 2018 20:38:12 +0300
Raw View
On 25 July 2018 at 20:34, Nicol Bolas <jmckesson@gmail.com> wrote:
> That is, P0709 is exception handling with better performance. That is its
> principle design.
Better performance for code that throws, maybe. For code that rarely
or never throws, maybe not.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAFk2RUaW8zyiMYrVwKH6jvuD1hzhgZq8G6YFz2QfZ-fdc_dhvA%40mail.gmail.com.
.
Author: inkwizytoryankes@gmail.com
Date: Wed, 25 Jul 2018 12:23:54 -0700 (PDT)
Raw View
------=_Part_9966_214187302.1532546634978
Content-Type: multipart/alternative;
boundary="----=_Part_9967_607522819.1532546634978"
------=_Part_9967_607522819.1532546634978
Content-Type: text/plain; charset="UTF-8"
On Wednesday, July 25, 2018 at 7:34:28 PM UTC+2, Nicol Bolas wrote:
>
> On Wednesday, July 25, 2018 at 4:30:44 AM UTC-4, Niall Douglas wrote:
>>
>> How does one manage the lifetime of the exception_ptr object if
>>>>> std::error cannot call a non-trivial destructor on its final destruction?
>>>>>
>>>>
>>>> Compiler magic. `std::error` can do it because the standard *says*
>>>> that it can.
>>>>
>>>
>>> I think I misunderstood what you were saying. The answer is still
>>> "compiler magic", but a different form.
>>>
>>> If you're talking about the throwing of `std::error` as an exception and
>>> its propagation up the call graph, that is a function of the static
>>> exception machinery. This is conceptually based on return values and the
>>> like, but the compiler is intimately involved. Therefore, it can choose to
>>> call `std::error`'s non-trivial destructor or not, as it sees fit, in a
>>> static way. After all, if it's "copying" the object from the current stack
>>> to the caller's value, then it knows that it can just do a memcpy and not
>>> call the destructor. Or stick it in a register. And that's a static thing.
>>>
>>> Once the object materializes in a way you can inspect it, then it acts
>>> like a regular object. Copying it bumps the reference counter, if one
>>> exists. Destroying it decrements the reference counter if it exists. And
>>> the like.
>>>
>>> The important compiler magic for `std::error` is its treatment during
>>> exception propagation, which user code cannot impinge upon.
>>>
>>
>> Ah, the "token exception throwing" model. I understand where you are at
>> now. In a similar place as Jacob, who wrote that counterproposal to mine in
>> that other thread.
>>
>> I think Herb did everyone a disfavour by using the phrase "static
>> exceptions" in his paper. We need to dispense with that phrase, it is
>> unhelpful and confusing because it has meaning in the mind of the beholder.
>>
>> I'll drop him a line there now and see if I can persuade him to revise
>> his paper with more clarifying terminology.
>>
>
> I may be wrong, but I think that you've misattributed the goals of P0709.
> I think Herb used the phrase "static exceptions" because it gives the
> *intended* impression. And I'm not sure that "deterministic exceptions"
> would give a better impression.
>
> "Static exceptions" tells you exactly what design P0709 outlines:
> exceptions, without the dynamic nature of them. Catches catch by the exact
> value thrown. Avenues of transmission from source to target is a static
> property of the executable. And so forth.
>
> That is, P0709 is exception handling with better performance. That is its
> principle design.
>
> While P0709 does spell out the mechanism of transmission, it doesn't
> require that specific implementation. Table-based implementations are still
> *allowed*; they're just not de-facto mandatory. And table-based
> transmission can't happen across ABI boundaries. But if the compiler can
> see all the code from throw to catch, then it can build an optimized static
> table for handling it.
>
> Or not, as it so chooses.
>
> You can see this design further in that P0709 mandates that
> `uncaught_exceptions` will still work, regardless of whether the exception
> passing through is static or dynamic. This means that things like
> `std::scope_fail` will work without changes.
>
>
Good point, this depend if we allow non-C++ code to intercept exceptions.
If yes then local unwind of static exception will need to increment and
decrement thread static variable that will be added to old result of
`uncaught_exceptions` (if dynamic one is converted to static then number of
dynamic exceptions should be reduced). Question is how much overhead will
do this changing of that variable.
Alternative we expose `uncaught_exceptions_add` and
`uncaught_exceptions_sub` but this will probably cause to much mess to be
worthy.
> Now, it may not be possible to do that for overhead-related reasons. But
> if it's not possible, then the eventual more fleshed out static exception
> design will have to provide *some *mechanism for telling the difference
> between an object being destroyed due to static exception unwinding and
> being destroyed due to normal local returns. That's an important aspect to
> exceptions, so it's an important aspect to "static exceptions".
>
> Similarly, one of the main reasons P0709 is fixed to using `std::error` as
> its static exception type is that this permits all static exception
> functions to transmit dynamic exceptions too. So if the receiver and sender
> are dynamic, then calling the sender through some static exception function
> won't break dynamic exceptions. Ensuring this is part-and-parcel of being a
> design for an exception system.
>
>
Custom static exception could terminate too in some cases if they wish not
propagate exceptions. Similar to use of `noexcept`, it too could break code
if someone else expect to unwind this function.
`std::error` is fully transparent, custom is based on opt-out (default is
transparent).
> By contrast, your view seems to be that "deterministic exceptions" are,
> first and foremost, a C design with some C++ syntactic sugar that looks
> suspiciously like C++'s exception mechanism. That is, it is not a priority
> in your design that `_Fails()` based code behaves like exceptions. So would
> your design provide a way to tell if an object is being destroyed due to an
> exception?
>
>
Automatic destruction know who calls it. If you use `_Catch(foo())` in C++
then no unwinding will be done, if you use `_Try(foo())` then we can go
exception path that could alter some thread static variable to give this
info for destructors. Of corse this is overhead. For C++ native syntax it
work same:
try
{
raii_type a;
foo(); //throws static exception
raii_type b;
}
catch(cutom_exception)
{
//code
}
//same as this pseudo code:
if (foo_exception)
{
thread_static_except_count++
a.~raii_type()
thread_static_except_count--
goto catch_cutom_exception
}
> By allowing `_Fails()` to provide types incompatible with `std::error`,
> you also allow such code to impede the flow of dynamic exceptions. That's
> not a priority for your design.
>
> But it is a priority for P0709.
>
> This seems to be a fundamental divergence of vision. You seem to want the
> C mechanism dressed up in C++ clothing; P0709 seems to want exceptions
> without the overhead.
>
Agree, I have too bit different visionand how it should work. And it could
not work if we what easy way to propagate dynamic exceptions.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/99148fa0-fe32-4e12-9836-c15299386d4c%40isocpp.org.
------=_Part_9967_607522819.1532546634978
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, July 25, 2018 at 7:34:28 PM UTC+2, N=
icol Bolas 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">On Wednesday, July 25, 2018 at 4:30:44 AM UTC-4, Niall Douglas wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-=
left:1px #ccc solid;padding-left:1ex"><blockquote class=3D"gmail_quote" sty=
le=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1e=
x"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" style=3D"margin:0;mar=
gin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><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>How does on=
e manage the lifetime of the exception_ptr object if std::error cannot call=
a non-trivial destructor on its final destruction?</div></div></blockquote=
><div><br></div><div>Compiler magic. `std::error` can do it because the sta=
ndard <i>says</i> that it can.<br></div></div></blockquote><div><br></div><=
div>I think I misunderstood what you were saying. The answer is still "=
;compiler magic", but a different form.</div><div><br></div><div>If yo=
u're talking about the throwing of `std::error` as an exception and its=
propagation up the call graph, that is a function of the static exception =
machinery. This is conceptually based on return values and the like, but th=
e compiler is intimately involved. Therefore, it can choose to call `std::e=
rror`'s non-trivial destructor or not, as it sees fit, in a static way.=
After all, if it's "copying" the object from the current sta=
ck to the caller's value, then it knows that it can just do a memcpy an=
d not call the destructor. Or stick it in a register. And that's a stat=
ic thing.</div><div><br></div><div>Once the object materializes in a way yo=
u can inspect it, then it acts like a regular object. Copying it bumps the =
reference counter, if one exists. Destroying it decrements the reference co=
unter if it exists. And the like.</div><div><br></div><div>The important co=
mpiler magic for `std::error` is its treatment during exception propagation=
, which user code cannot impinge upon.<br></div></div></blockquote><div><br=
></div><div>Ah, the "token exception throwing" model. I understan=
d where you are at now. In a similar place as Jacob, who wrote that counter=
proposal to mine in that other thread.</div><div><br></div><div>I think Her=
b did everyone a disfavour by using the phrase "static exceptions"=
; in his paper. We need to dispense with that phrase, it is unhelpful and c=
onfusing because it has meaning in the mind of the beholder.</div><div><br>=
</div><div>I'll drop him a line there now and see if I can persuade him=
to revise his paper with more clarifying terminology.</div></blockquote><d=
iv><br></div><div>I may be wrong, but I think that you've misattributed=
the goals of P0709. I think Herb used the phrase "static exceptions&q=
uot; because it gives the <i>intended</i> impression. And I'm not sure =
that "deterministic exceptions" would give a better impression.</=
div><div><br></div><div>"Static exceptions" tells you exactly wha=
t design P0709 outlines: exceptions, without the dynamic nature of them. Ca=
tches catch by the exact value thrown. Avenues of transmission from source =
to target is a static property of the executable. And so forth.</div><div><=
br></div><div>That is, P0709 is exception handling with better performance.=
That is its principle design.</div><div><br></div><div>While P0709 does sp=
ell out the mechanism of transmission, it doesn't require that specific=
implementation. Table-based implementations are still <i>allowed</i>; they=
're just not de-facto mandatory. And table-based transmission can't=
happen across ABI boundaries. But if the compiler can see all the code fro=
m throw to catch, then it can build an optimized static table for handling =
it.</div><div><br></div><div>Or not, as it so chooses.</div><div><br></div>=
<div>You can see this design further in that P0709 mandates that `uncaught_=
exceptions` will still work, regardless of whether the exception passing th=
rough is static or dynamic. This means that things like `std::scope_fail` w=
ill work without changes.</div><div><br></div></div></blockquote><div><br><=
/div><div>Good point, this depend if we allow non-C++ code to intercept exc=
eptions. If yes then local unwind of static exception will need to incremen=
t and decrement thread static variable that will be added to old result of =
`uncaught_exceptions` (if dynamic one is converted to static then number of=
dynamic exceptions should be reduced). Question is how much overhead will =
do this changing of that variable.</div><div><br></div><div>Alternative we =
expose `uncaught_exceptions_add` and `uncaught_exceptions_sub` but this wil=
l probably cause to much mess to be worthy.<br></div><div>=C2=A0</div><bloc=
kquote 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><div>No=
w, it may not be possible to do that for overhead-related reasons. But if i=
t's not possible, then the eventual more fleshed out static exception d=
esign will have to provide <i>some </i>mechanism for telling the difference=
between an object being destroyed due to static exception unwinding and be=
ing destroyed due to normal local returns. That's an important aspect t=
o exceptions, so it's an important aspect to "static exceptions&qu=
ot;.</div><div><br></div><div>Similarly, one of the main reasons P0709 is f=
ixed to using `std::error` as its static exception type is that this permit=
s all static exception functions to transmit dynamic exceptions too. So if =
the receiver and sender are dynamic, then calling the sender through some s=
tatic exception function won't break dynamic exceptions. Ensuring this =
is part-and-parcel of being a design for an exception system.<br></div><div=
><br></div></div></blockquote><div><br></div><div>Custom static exception c=
ould terminate too in some cases if they wish not propagate exceptions. Sim=
ilar to use of `noexcept`, it too could break code if someone else expect t=
o unwind this function.</div><div>`std::error`=C2=A0 is fully transparent, =
custom is based on opt-out (default is transparent).<br></div><div>=C2=A0</=
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></di=
v><div>By contrast, your view seems to be that "deterministic exceptio=
ns" are, first and foremost, a C design with some C++ syntactic sugar =
that looks suspiciously like C++'s exception mechanism. That is, it is =
not a priority in your design that `_Fails()` based code behaves like excep=
tions. So would your design provide a way to tell if an object is being des=
troyed due to an exception?</div><div><br></div></div></blockquote><div><br=
></div><div>Automatic destruction know who calls it. If you use `_Catch(foo=
())` in C++ then no unwinding will be done, if you use `_Try(foo())` then w=
e can go exception path that could alter some thread static variable to giv=
e this info for destructors. Of corse this is overhead. For C++ native synt=
ax it work same:</div><div><br></div><div><div style=3D"background-color: r=
gb(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; b=
order-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code c=
lass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #0=
08;" class=3D"styled-by-prettify">try</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 raii_type a</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br>=C2=A0 foo</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">();</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettif=
y">//throws static exception</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br>=C2=A0 raii_type b</span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">=
catch</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">cutom_exceptio=
n</span><span style=3D"color: #660;" class=3D"styled-by-prettify">)</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">{</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"><br>=C2=A0 </span><span style=3D"=
color: #800;" class=3D"styled-by-prettify">//code</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">//same as this pseudo code:</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">if</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify">foo_exception</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 t=
hread_static_except_count</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">++</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br>=C2=A0 a</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">.~</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
>raii_type</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=
=A0 thread_static_except_count</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">--</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br>=C2=A0 </span><span style=3D"color: #008;" class=3D"styled-=
by-prettify">goto</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> catch_cutom_exception<br></span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">}</span></div></code></div><br></div><div>=C2=A0</d=
iv><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=
><div>By allowing `_Fails()` to provide types incompatible with `std::error=
`, you also allow such code to impede the flow of dynamic exceptions. That&=
#39;s not a priority for your design.</div><div><br></div><div>But it is a =
priority for P0709.<br></div><div><br></div><div>This seems to be a fundame=
ntal divergence of vision. You seem to want the C mechanism dressed up in C=
++ clothing; P0709 seems to want exceptions without the overhead.<br></div>=
</div></blockquote><div><br></div><div>Agree, I have too bit different visi=
onand=C2=A0 how it should work. And it could not work if we what easy way t=
o propagate dynamic exceptions.</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/99148fa0-fe32-4e12-9836-c15299386d4c%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/99148fa0-fe32-4e12-9836-c15299386d4c=
%40isocpp.org</a>.<br />
------=_Part_9967_607522819.1532546634978--
------=_Part_9966_214187302.1532546634978--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Wed, 25 Jul 2018 12:53:18 -0700 (PDT)
Raw View
------=_Part_9607_1547341073.1532548399036
Content-Type: multipart/alternative;
boundary="----=_Part_9608_925851523.1532548399036"
------=_Part_9608_925851523.1532548399036
Content-Type: text/plain; charset="UTF-8"
>
> Position-independence is an even more high-level property; it cannot be
> built up class by class; it is an emergent property of the *entire data
> structure*. For example, a struct containing members of type
> offset_ptr<T> is definitely not trivially relocatable, and counts as
> "position-independent" only if all those offset_ptrs point into the same
> shared memory segment where the struct itself already lives. If any one of
> those offset_ptrs points to global data, or points to the process's own
> heap or stack, then the data structure will *not* be shareable between
> different processes.
>
Indeed. But I should clarify I'm only in the early stages of specifying the
changes. I've got about as far as a new mapped storage duration, and it has
various properties. Once I'm fully happy with it, I'll start into a very
unambitious set of extensions to object lifetime, leave lots of stuff as UB
i.e. to be defined later, and we'll see where we get to.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/078ede2a-ebb7-4039-8375-3d4c5d656996%40isocpp.org.
------=_Part_9608_925851523.1532548399036
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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"><div>Position-independence is an even m=
ore high-level property; it cannot be built up class by class; it is an eme=
rgent property of the <i>entire data structure</i>.=C2=A0 For example, a st=
ruct containing members of type offset_ptr<T> is definitely not trivi=
ally relocatable, and counts as "position-independent" only if al=
l those offset_ptrs point into the same shared memory segment where the str=
uct itself already lives. If any one of those offset_ptrs points to global =
data, or points to the process's own heap or stack, then the data struc=
ture will <i>not</i> be shareable between different processes.</div></div><=
/div></div></blockquote><div><br></div><div>Indeed. But I should clarify I&=
#39;m only in the early stages of specifying the changes. I've got abou=
t as far as a new mapped storage duration, and it has various properties. O=
nce I'm fully happy with it, I'll start into a very unambitious set=
of extensions to object lifetime, leave lots of stuff as UB i.e. to be def=
ined later, and we'll see where we get to.</div><div><br></div><div>Nia=
ll</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/078ede2a-ebb7-4039-8375-3d4c5d656996%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/078ede2a-ebb7-4039-8375-3d4c5d656996=
%40isocpp.org</a>.<br />
------=_Part_9608_925851523.1532548399036--
------=_Part_9607_1547341073.1532548399036--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Wed, 25 Jul 2018 13:18:21 -0700 (PDT)
Raw View
------=_Part_9981_205474501.1532549901841
Content-Type: multipart/alternative;
boundary="----=_Part_9982_1254669707.1532549901841"
------=_Part_9982_1254669707.1532549901841
Content-Type: text/plain; charset="UTF-8"
>
>
> I may be wrong, but I think that you've misattributed the goals of P0709.
> I think Herb used the phrase "static exceptions" because it gives the
> *intended* impression. And I'm not sure that "deterministic exceptions"
> would give a better impression.
>
P0709R0 was carefully written to not upset people with too much detail
which people would either bikeshed over, or would get overwhelmed by. As
time goes along, more detail will get filled in, simple terminology will
get replaced with more specific terminology and so on.
>
> "Static exceptions" tells you exactly what design P0709 outlines:
> exceptions, without the dynamic nature of them. Catches catch by the exact
> value thrown. Avenues of transmission from source to target is a static
> property of the executable. And so forth.
>
Sure.
>
> That is, P0709 is exception handling with better performance. That is its
> principle design.
>
Not exactly. Note the title of the paper: *Zero overhead*. We really do
mean *zero*, as in non-measurable in every way, whether in binary bloat or
execution time.
>
> You can see this design further in that P0709 mandates that
> `uncaught_exceptions` will still work, regardless of whether the exception
> passing through is static or dynamic. This means that things like
> `std::scope_fail` will work without changes.
>
In the *default* i.e. *compatibility* compiler setting yes, it continues to
work. Otherwise legacy code breaks. In my opinion, I don't believe in fact
that one can change legacy exception throws continuing to use EH tables in
any future C++, otherwise backwards binary compatibility is broken. So,
going into the future, the default compiler setting still implements legacy
exception throws via the current mechanism, and deterministic exception
throws via the new mechanism. P1028 was specifically designed to arbitrate
seamlessly between both mechanisms, so everything "just works".
But Herb has been very clear in his desire for a compiler switch which
makes *all *exception throws deterministic at the cost of breaking
backwards binary compatibility, and legacy exception throws are emulated
via deterministic throws. That eliminates EH tables entirely. I, personally
speaking, feel that this mode needs to make uncaught_exceptions() only
apply to throws of legacy exceptions only, because otherwise we mandate
thread local storage, and that's a serious no-no for the SG14 crowd (and
rightly so).
Moreover, uncaught_exceptions() becomes meaningless in a deterministic
exception throwing world. Deterministic exception throws are ordinary
control flow. They're a different beast to legacy exceptions, they have
different use cases. They don't have the strictures of legacy exception
design patterns. They have new ones.
>
> Now, it may not be possible to do that for overhead-related reasons. But
> if it's not possible, then the eventual more fleshed out static exception
> design will have to provide *some *mechanism for telling the difference
> between an object being destroyed due to static exception unwinding and
> being destroyed due to normal local returns. That's an important aspect to
> exceptions, so it's an important aspect to "static exceptions".
>
What might be possible, as a compromise, is that unwinding of std::error
specifically throws will increment and decrement the thread local count of
extant exception throws. But throws of other deterministic exceptions would
not. I'll drop a note to Herb about that too extending the note I sent him
earlier with this idea.
>
> Similarly, one of the main reasons P0709 is fixed to using `std::error` as
> its static exception type is that this permits all static exception
> functions to transmit dynamic exceptions too. So if the receiver and sender
> are dynamic, then calling the sender through some static exception function
> won't break dynamic exceptions. Ensuring this is part-and-parcel of being a
> design for an exception system.
>
P1028 provides that mechanism.
>
> By contrast, your view seems to be that "deterministic exceptions" are,
> first and foremost, a C design with some C++ syntactic sugar that looks
> suspiciously like C++'s exception mechanism. That is, it is not a priority
> in your design that `_Fails()` based code behaves like exceptions. So would
> your design provide a way to tell if an object is being destroyed due to an
> exception?
>
My priority is that failure be absolutely deterministic. No accessing cold
cache somewhere to increment a current exception count. No accessing cold
cache EH tables. Anything less than that is a bad proposal.
>
> By allowing `_Fails()` to provide types incompatible with `std::error`,
> you also allow such code to impede the flow of dynamic exceptions. That's
> not a priority for your design.
>
Whoever said that _Fails(T) was not compatible with std::error?
Of course it is, if P1028's proposed std::error is chosen. I may not have
thought of everything, but I hardly initiated generating a consensus
between C++ and C without seamless interoperation high on my priority list.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/337532a5-4a6f-4c10-9de1-0cec3d59d559%40isocpp.org.
------=_Part_9982_1254669707.1532549901841
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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><br></div><div>I may be wrong, but I think that you've misattr=
ibuted the goals of P0709. I think Herb used the phrase "static except=
ions" because it gives the <i>intended</i> impression. And I'm not=
sure that "deterministic exceptions" would give a better impress=
ion.</div></div></blockquote><div><br></div><div>P0709R0 was carefully writ=
ten to not upset people with too much detail which people would either bike=
shed over, or would get overwhelmed by. As time goes along, more detail wil=
l get filled in, simple terminology will get replaced with more specific te=
rminology and so on.=C2=A0</div><div>=C2=A0</div><blockquote class=3D"gmail=
_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;p=
adding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>"Static except=
ions" tells you exactly what design P0709 outlines: exceptions, withou=
t the dynamic nature of them. Catches catch by the exact value thrown. Aven=
ues of transmission from source to target is a static property of the execu=
table. And so forth.</div></div></blockquote><div><br></div><div>Sure.</div=
><div>=C2=A0</div><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><br></div><div>That is, P0709 is exception handling with better p=
erformance. That is its principle design.</div></div></blockquote><div><br>=
</div><div>Not exactly. Note the title of the paper: <i>Zero overhead</i>. =
We really do mean <b>zero</b>, as in non-measurable in every way, whether i=
n binary bloat or execution time.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>You can se=
e this design further in that P0709 mandates that `uncaught_exceptions` wil=
l still work, regardless of whether the exception passing through is static=
or dynamic. This means that things like `std::scope_fail` will work withou=
t changes.</div></div></blockquote><div><br></div><div>In the <i>default</i=
>=C2=A0i.e. <i>compatibility</i>=C2=A0compiler setting yes, it continues to=
work. Otherwise legacy code breaks. In my opinion, I don't believe in =
fact that one can change legacy exception throws continuing to use EH table=
s in any future C++, otherwise backwards binary compatibility is broken. So=
, going into the future, the default compiler setting still implements lega=
cy exception throws via the current mechanism, and deterministic exception =
throws via the new mechanism. P1028 was specifically designed to arbitrate =
seamlessly between both mechanisms, so everything "just works".</=
div><div><br></div><div>But Herb has been very clear in his desire for a co=
mpiler switch which makes <b>all </b>exception throws deterministic at the =
cost of breaking backwards binary compatibility, and legacy exception throw=
s are emulated via deterministic throws. That eliminates EH tables entirely=
.. I, personally speaking, feel that this mode needs to make uncaught_except=
ions() only apply to throws of legacy exceptions only, because otherwise we=
mandate thread local storage, and that's a serious no-no for the SG14 =
crowd (and rightly so).</div><div><br></div><div>Moreover, uncaught_excepti=
ons() becomes meaningless in a deterministic exception throwing world. Dete=
rministic exception throws are ordinary control flow. They're a differe=
nt beast to legacy exceptions, they have different use cases. They don'=
t have the strictures of legacy exception design patterns. They have new on=
es.</div><div>=C2=A0</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><br></div><div>Now, it may not be possible to do that for=
overhead-related reasons. But if it's not possible, then the eventual =
more fleshed out static exception design will have to provide <i>some </i>m=
echanism for telling the difference between an object being destroyed due t=
o static exception unwinding and being destroyed due to normal local return=
s. That's an important aspect to exceptions, so it's an important a=
spect to "static exceptions".</div></div></blockquote><div><br></=
div><div>What might be possible, as a compromise, is that unwinding of std:=
:error specifically throws will increment and decrement the thread local co=
unt of extant exception throws. But throws of other deterministic exception=
s would not. I'll drop a note to Herb about that too extending the note=
I sent him earlier with this idea.</div><div>=C2=A0</div><blockquote class=
=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #cc=
c solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>Similarly,=
one of the main reasons P0709 is fixed to using `std::error` as its static=
exception type is that this permits all static exception functions to tran=
smit dynamic exceptions too. So if the receiver and sender are dynamic, the=
n calling the sender through some static exception function won't break=
dynamic exceptions. Ensuring this is part-and-parcel of being a design for=
an exception system.<br></div></div></blockquote><div><br></div><div>P1028=
provides that mechanism.</div><div>=C2=A0</div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr"><div></div><div><br></div><div>By contra=
st, your view seems to be that "deterministic exceptions" are, fi=
rst and foremost, a C design with some C++ syntactic sugar that looks suspi=
ciously like C++'s exception mechanism. That is, it is not a priority i=
n your design that `_Fails()` based code behaves like exceptions. So would =
your design provide a way to tell if an object is being destroyed due to an=
exception?</div></div></blockquote><div><br></div><div>My priority is that=
failure be absolutely deterministic. No accessing cold cache somewhere to =
increment a current exception count. No accessing cold cache EH tables. Any=
thing less than that is a bad proposal.</div><div>=C2=A0</div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>By all=
owing `_Fails()` to provide types incompatible with `std::error`, you also =
allow such code to impede the flow of dynamic exceptions. That's not a =
priority for your design.</div></div></blockquote><div><br></div><div>Whoev=
er said that _Fails(T) was not compatible with std::error?</div><div><br></=
div><div>Of course it is, if P1028's proposed std::error is chosen. I m=
ay not have thought of everything, but I hardly initiated generating a cons=
ensus between C++ and C without seamless interoperation high on my priority=
list.</div><div><br></div><div>Niall</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/337532a5-4a6f-4c10-9de1-0cec3d59d559%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/337532a5-4a6f-4c10-9de1-0cec3d59d559=
%40isocpp.org</a>.<br />
------=_Part_9982_1254669707.1532549901841--
------=_Part_9981_205474501.1532549901841--
.
Author: mihailnajdenov@gmail.com
Date: Thu, 26 Jul 2018 01:54:33 -0700 (PDT)
Raw View
------=_Part_9902_276144743.1532595274019
Content-Type: multipart/alternative;
boundary="----=_Part_9903_1421648621.1532595274019"
------=_Part_9903_1421648621.1532595274019
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wednesday, July 25, 2018 at 8:15:47 PM UTC+3, Ga=C5=A1per A=C5=BEman wro=
te:
>
>
>
> On Wed, Jul 25, 2018 at 5:44 PM, <mihailn...@gmail.com <javascript:>>=20
> wrote:
>
>>
>>
>> On Wednesday, July 25, 2018 at 9:42:15 AM UTC+3, Arthur O'Dwyer wrote:
>>>
>>> On Mon, Jul 23, 2018 at 1:06 PM, Nicol Bolas <jmck...@gmail.com> wrote:
>>>
>>>> On Monday, July 23, 2018 at 3:00:55 PM UTC-4, mihailn...@gmail.com=20
>>>> wrote:
>>>>>
>>>>> On Monday, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:
>>>>>>
>>>>>> But as Arthur noted, this definition would exempt an entire category=
=20
>>>>>> of objects like `std::list`, where move does not leave them in a "tr=
ivial"=20
>>>>>> state. The P1144 definition of relocation is that "move+destroy" is=
=20
>>>>>> equivalent to "memcpy+drop". That's not the same thing as declaring =
that=20
>>>>>> movement leaves the object in a "trivial state".
>>>>>>
>>>>> =20
>>>>> I see, so 1144 "works" even if after 'move', the object needs to be=
=20
>>>>> non-trivially destroyed. Yeah, my observations do not apply then.
>>>>>
>>>>> [...]
>>>>>
>>>>
>>>> But you're right, that it should talk about cases like `std::list`. An=
d=20
>>>> I'm rather surprised that it didn't bring them up.
>>>>
>>>
>>> Well, here's some revolting news: `std::list` *is not* trivially=20
>>> relocatable on any vendor today! I have just added a new subsection to=
=20
>>> Appendix C, giving `std::list` alongside my other examples of=20
>>> non-trivially-relocatable types:
>>>
>>> =3D=3D=3D=3D=3D
>>> std::list needs somewhere to store its "past-the-end" node, commonly=20
>>> referred to as the "sentinel node." If the sentinel node is allocated o=
n=20
>>> the heap, then std::list can be trivially relocatable; but if the senti=
nel=20
>>> node is placed within the list object itself (as happens on libc++ and=
=20
>>> libstdc++), then relocating the list object will necessitate fixing up =
a=20
>>> pair of pointers elsewhere on the heap. This fixup cannot be simulated =
by=20
>>> memcpy.
>>>
>>
>> But this is easily fixable by the implementation, no? They just need to=
=20
>> make the node (inline?) static and point to it instead. Could there be a=
=20
>> problem all lists having the same sentinel? =20
>>
>
> =20
> It's a doubly-linked list. You either have a branch in every iterator to=
=20
> check whether you're at a sentinel and then *do something else* to=20
> implement -- for the sentinel node, or have a different sentinel that loo=
ks=20
> like a normal node and just look at the pointer :).
> =20
>
Of course, my bad, nodes can't be shared.
Well, in any case I believe most implementations will prefer=20
self-referential than heap, which basically kills any non-"destructive=20
move" "relocation".
It also makes it obvious, trivially_destructible_after_move is not good=20
enough.
It seems also*, *we can't really go without "drop" when we handle moving=20
multiple objects in one go as there is no way the compiler can tell a=20
memcpy of a bunch of objects is considered move.
Niall, how does 1029 envisions moving multiple (contiguous) objects? It=20
seems only object-by-object relocation is optimized "out of the box"?
=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.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/dd179d10-670c-4406-898f-203d22dea8c4%40isocpp.or=
g.
------=_Part_9903_1421648621.1532595274019
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Wednesday, July 25, 2018 at 8:15:47 PM UTC+3, G=
a=C5=A1per A=C5=BEman wrote:<blockquote class=3D"gmail_quote" style=3D"marg=
in: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><d=
iv dir=3D"ltr"><br><div><br><div class=3D"gmail_quote">On Wed, Jul 25, 2018=
at 5:44 PM, <span dir=3D"ltr"><<a onmousedown=3D"this.href=3D'java=
script:';return true;" onclick=3D"this.href=3D'javascript:';ret=
urn true;" href=3D"javascript:" target=3D"_blank" rel=3D"nofollow" gdf-obfu=
scated-mailto=3D"mUbw_MGDDwAJ">mihailn...@gmail.com</a>></span> wrote:<b=
r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><br><br>On Wednesday, Jul=
y 25, 2018 at 9:42:15 AM UTC+3, Arthur O'Dwyer wrote:<span><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">On Mon, Jul 23, 2018 at 1:06 P=
M, Nicol Bolas <span dir=3D"ltr"><<a rel=3D"nofollow">jmck...@gmail.com<=
/a>></span> wrote:<br><div><div class=3D"gmail_quote"><blockquote class=
=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo=
rder-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">=
<div dir=3D"ltr"><div><div>On Monday, July 23, 2018 at 3:00:55 PM UTC-4, <a=
>mihailn...@gmail.com</a> wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;bord=
er-left-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr">On Monday=
, July 23, 2018 at 4:56:50 PM UTC+3, Nicol Bolas wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;borde=
r-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><di=
v dir=3D"ltr"><div></div><div>But as Arthur noted, this definition would ex=
empt an entire category of objects like `std::list`, where move does not le=
ave them in a "trivial" state. The P1144 definition of relocation=
is that "move+destroy" is equivalent to "memcpy+drop".=
That's not the same thing as declaring that movement leaves the object=
in a "trivial state".<br></div></div></blockquote><div>=C2=A0</d=
iv><div>I see, so 1144 "works" even if after 'move', the =
object needs to be non-trivially destroyed. Yeah, my observations do not ap=
ply then.</div><div><br></div><div>[...]</div></div></blockquote></div></di=
v><div><br></div><div>But you're right, that it should talk about cases=
like `std::list`. And I'm rather surprised that it didn't bring th=
em up.</div></div></blockquote><div><br></div><div>Well, here's some re=
volting news: `std::list` <i><b>is not</b></i> trivially relocatable on any=
vendor today!=C2=A0=C2=A0I have just added a new subsection to Appendix C,=
giving `std::list` alongside my other examples of non-trivially-relocatabl=
e types:</div><div><br></div><div>=3D=3D=3D=3D=3D</div><div><div>std::list =
needs somewhere to store its "past-the-end" node, commonly referr=
ed to as the "sentinel node." If the sentinel node is allocated o=
n the heap, then std::list can be trivially relocatable; but if the sentine=
l node is placed within the list object itself (as happens on libc++ and li=
bstdc++), then relocating the list object will necessitate fixing up a pair=
of pointers elsewhere on the heap. This fixup cannot be simulated by memcp=
y.</div></div></div></div></div></blockquote><div><br></div></span><div>But=
this is easily fixable by the implementation, no? They just need to make t=
he node (inline?) static and point to it instead. Could there be a problem =
all lists having the same sentinel? =C2=A0</div></div></blockquote><div><br=
></div></div></div></div></blockquote><div>=C2=A0</div><blockquote class=3D=
"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc s=
olid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><=
div></div><div>It's a doubly-linked list. You either have a branch in e=
very iterator to check whether you're at a sentinel and then *do someth=
ing else* to implement -- for the sentinel node, or have a different sentin=
el that looks like a normal node and just look at the pointer :).</div><div=
>=C2=A0</div></div></div></div></blockquote><div><div style=3D"background-c=
olor: transparent; border-bottom-color: rgb(34, 34, 34); border-bottom-styl=
e: none; border-bottom-width: 0px; border-image-outset: 0; border-image-rep=
eat: stretch; border-image-slice: 100%; border-image-source: none; border-i=
mage-width: 1; border-left-color: rgb(34, 34, 34); border-left-style: none;=
border-left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-=
style: none; border-right-width: 0px; border-top-color: rgb(34, 34, 34); bo=
rder-top-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-f=
amily: &quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; =
font-size: 13px; font-style: normal; font-variant: normal; font-weight: 400=
; letter-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-righ=
t: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px=
; padding-right: 0px; padding-top: 0px; text-align: left; text-decoration: =
none; text-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0p=
x; white-space: normal; word-spacing: 0px;"><br style=3D"background-attachm=
ent: scroll; background-clip: border-box; background-color: transparent; ba=
ckground-image: none; background-origin: padding-box; background-position-x=
: 0%; background-position-y: 0%; background-repeat: repeat; background-size=
: auto; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bo=
rder-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretc=
h; border-image-slice: 100%; border-image-source: none; border-image-width:=
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-lef=
t-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none=
; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-st=
yle: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &=
;quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: =
13px; height: auto; margin-bottom: 0px; margin-left: 0px; margin-right: 0px=
; margin-top: 0px; min-width: 0px; overflow: visible; overflow-x: visible; =
overflow-y: visible; padding-bottom: 0px; padding-left: 0px; padding-right:=
0px; padding-top: 0px;"></div><div style=3D"background-color: transparent;=
border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; border-bo=
ttom-width: 0px; border-image-outset: 0; border-image-repeat: stretch; bord=
er-image-slice: 100%; border-image-source: none; border-image-width: 1; bor=
der-left-color: rgb(34, 34, 34); border-left-style: none; border-left-width=
: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none; borde=
r-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-style: no=
ne; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &quot;A=
rial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; f=
ont-style: normal; font-variant: normal; font-weight: 400; letter-spacing: =
normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top=
: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0=
px; padding-top: 0px; text-align: left; text-decoration: none; text-indent:=
0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: no=
rmal; word-spacing: 0px;">Of course, my bad, nodes can't be shared.<br>=
</div><div style=3D"background-color: transparent; border-bottom-color: rgb=
(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-i=
mage-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; bor=
der-image-source: none; border-image-width: 1; border-left-color: rgb(34, 3=
4, 34); border-left-style: none; border-left-width: 0px; border-right-color=
: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; borde=
r-top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px=
; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;=
Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-v=
ariant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; paddin=
g-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; tex=
t-align: left; text-decoration: none; text-indent: 0px; text-transform: non=
e; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"=
><br style=3D"background-attachment: scroll; background-clip: border-box; b=
ackground-color: transparent; background-image: none; background-origin: pa=
dding-box; background-position-x: 0%; background-position-y: 0%; background=
-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rg=
b(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&a=
mp;quot;,sans-serif; font-size: 13px; height: auto; margin-bottom: 0px; mar=
gin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0px; overflow=
: visible; overflow-x: visible; overflow-y: visible; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div style=
=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34); bo=
rder-bottom-style: none; border-bottom-width: 0px; border-image-outset: 0; =
border-image-repeat: stretch; border-image-slice: 100%; border-image-source=
: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); border-l=
eft-style: none; border-left-width: 0px; border-right-color: rgb(34, 34, 34=
); border-right-style: none; border-right-width: 0px; border-top-color: rgb=
(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb(34,=
34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&qu=
ot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal; =
font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left: =
0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px; p=
adding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; t=
ext-decoration: none; text-indent: 0px; text-transform: none; -webkit-text-=
stroke-width: 0px; white-space: normal; word-spacing: 0px;">Well, in any ca=
se I believe most implementations will prefer self-referential than heap, w=
hich basically kills any non-"destructive move" "relocation&=
quot;.</div><div style=3D"background-color: transparent; border-bottom-colo=
r: rgb(34, 34, 34); border-bottom-style: none; border-bottom-width: 0px; bo=
rder-image-outset: 0; border-image-repeat: stretch; border-image-slice: 100=
%; border-image-source: none; border-image-width: 1; border-left-color: rgb=
(34, 34, 34); border-left-style: none; border-left-width: 0px; border-right=
-color: rgb(34, 34, 34); border-right-style: none; border-right-width: 0px;=
border-top-color: rgb(34, 34, 34); border-top-style: none; border-top-widt=
h: 0px; color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&=
;quot;Helvetica&quot;,sans-serif; font-size: 13px; font-style: normal; =
font-variant: normal; font-weight: 400; letter-spacing: normal; margin-bott=
om: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; =
padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0p=
x; text-align: left; text-decoration: none; text-indent: 0px; text-transfor=
m: none; -webkit-text-stroke-width: 0px; white-space: normal; word-spacing:=
0px;"><br style=3D"background-attachment: scroll; background-clip: border-=
box; background-color: transparent; background-image: none; background-orig=
in: padding-box; background-position-x: 0%; background-position-y: 0%; back=
ground-repeat: repeat; background-size: auto; border-bottom-color: rgb(34, =
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-=
outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-i=
mage-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34=
); border-left-style: none; border-left-width: 0px; border-right-color: rgb=
(34, 34, 34); border-right-style: none; border-right-width: 0px; border-top=
-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; col=
or: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helve=
tica&quot;,sans-serif; font-size: 13px; height: auto; margin-bottom: 0p=
x; margin-left: 0px; margin-right: 0px; margin-top: 0px; min-width: 0px; ov=
erflow: visible; overflow-x: visible; overflow-y: visible; padding-bottom: =
0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"></div><div s=
tyle=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34)=
; border-bottom-style: none; border-bottom-width: 0px; border-image-outset:=
0; border-image-repeat: stretch; border-image-slice: 100%; border-image-so=
urce: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bord=
er-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 34=
, 34); border-right-style: none; border-right-width: 0px; border-top-color:=
rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rgb=
(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&am=
p;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: norm=
al; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-le=
ft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0p=
x; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: lef=
t; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-t=
ext-stroke-width: 0px; white-space: normal; word-spacing: 0px;">It also mak=
es it obvious, trivially_destructible_after_move is not good enough.<br></d=
iv><div style=3D"background-color: transparent; border-bottom-color: rgb(34=
, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-imag=
e-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border=
-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, =
34); border-left-style: none; border-left-width: 0px; border-right-color: r=
gb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-t=
op-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; c=
olor: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Hel=
vetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-vari=
ant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; =
margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-b=
ottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-a=
lign: left; text-decoration: none; text-indent: 0px; text-transform: none; =
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><s=
pan style=3D"background-color: transparent; border-bottom-color: rgb(34, 34=
, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-ou=
tset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-ima=
ge-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34);=
border-left-style: none; border-left-width: 0px; border-right-color: rgb(3=
4, 34, 34); border-right-style: none; border-right-width: 0px; border-top-c=
olor: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color=
: rgb(34, 34, 34); display: inline; float: none; font-family: &quot;Ari=
al&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; fon=
t-style: normal; font-variant: normal; font-weight: 400; letter-spacing: no=
rmal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: =
0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0px=
; padding-top: 0px; text-align: left; text-decoration: none; text-indent: 0=
px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: norm=
al; word-spacing: 0px;"><br></span></div><div style=3D"background-color: tr=
ansparent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none;=
border-bottom-width: 0px; border-image-outset: 0; border-image-repeat: str=
etch; border-image-slice: 100%; border-image-source: none; border-image-wid=
th: 1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-=
left-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: n=
one; border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top=
-style: none; border-top-width: 0px; color: rgb(34, 34, 34); font-family: &=
amp;quot;Arial&quot;,&quot;Helvetica&quot;,sans-serif; font-siz=
e: 13px; font-style: normal; font-variant: normal; font-weight: 400; letter=
-spacing: normal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; =
margin-top: 0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; paddin=
g-right: 0px; padding-top: 0px; text-align: left; text-decoration: none; te=
xt-indent: 0px; text-transform: none; -webkit-text-stroke-width: 0px; white=
-space: normal; word-spacing: 0px;"><span style=3D"background-color: transp=
arent; border-bottom-color: rgb(34, 34, 34); border-bottom-style: none; bor=
der-bottom-width: 0px; border-image-outset: 0; border-image-repeat: stretch=
; border-image-slice: 100%; border-image-source: none; border-image-width: =
1; border-left-color: rgb(34, 34, 34); border-left-style: none; border-left=
-width: 0px; border-right-color: rgb(34, 34, 34); border-right-style: none;=
border-right-width: 0px; border-top-color: rgb(34, 34, 34); border-top-sty=
le: none; border-top-width: 0px; color: rgb(34, 34, 34); display: inline; f=
loat: none; font-family: &quot;Arial&quot;,&quot;Helvetica&=
quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: normal=
; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-left=
: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0px;=
padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left;=
text-decoration: none; text-indent: 0px; text-transform: none; -webkit-tex=
t-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br></span></=
div><div style=3D"background-color: transparent; border-bottom-color: rgb(3=
4, 34, 34); border-bottom-style: none; border-bottom-width: 0px; border-ima=
ge-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; borde=
r-image-source: none; border-image-width: 1; border-left-color: rgb(34, 34,=
34); border-left-style: none; border-left-width: 0px; border-right-color: =
rgb(34, 34, 34); border-right-style: none; border-right-width: 0px; border-=
top-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; =
color: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;He=
lvetica&quot;,sans-serif; font-size: 13px; font-style: normal; font-var=
iant: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px;=
margin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-=
bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-=
align: left; text-decoration: none; text-indent: 0px; text-transform: none;=
-webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><=
span style=3D"background-color: transparent; border-bottom-color: rgb(34, 3=
4, 34); border-bottom-style: none; border-bottom-width: 0px; border-image-o=
utset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-im=
age-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 34)=
; border-left-style: none; border-left-width: 0px; border-right-color: rgb(=
34, 34, 34); border-right-style: none; border-right-width: 0px; border-top-=
color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; colo=
r: rgb(34, 34, 34); display: inline; float: none; font-family: &quot;Ar=
ial&quot;,&quot;Helvetica&quot;,sans-serif; font-size: 13px; fo=
nt-style: normal; font-variant: normal; font-weight: 400; letter-spacing: n=
ormal; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top:=
0px; orphans: 2; padding-bottom: 0px; padding-left: 0px; padding-right: 0p=
x; padding-top: 0px; text-align: left; text-decoration: none; text-indent: =
0px; text-transform: none; -webkit-text-stroke-width: 0px; white-space: nor=
mal; word-spacing: 0px;"><div>It seems also<i><b>, </b></i>we can't rea=
lly go without "drop" when we handle moving multiple objects in o=
ne go as there is no way the compiler can tell a memcpy of a bunch of objec=
ts is considered move.<br></div><div><br></div><div>Niall, how does 1029 en=
visions moving multiple (contiguous) objects? It seems only object-by-objec=
t relocation is optimized "out of the box"?</div><div><i></i><b><=
/b><b></b><i></i><br></div><div><br></div><div><br></div></span></div><div =
style=3D"background-color: transparent; border-bottom-color: rgb(34, 34, 34=
); border-bottom-style: none; border-bottom-width: 0px; border-image-outset=
: 0; border-image-repeat: stretch; border-image-slice: 100%; border-image-s=
ource: none; border-image-width: 1; border-left-color: rgb(34, 34, 34); bor=
der-left-style: none; border-left-width: 0px; border-right-color: rgb(34, 3=
4, 34); border-right-style: none; border-right-width: 0px; border-top-color=
: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; color: rg=
b(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helvetica&a=
mp;quot;,sans-serif; font-size: 13px; font-style: normal; font-variant: nor=
mal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; margin-l=
eft: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bottom: 0=
px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: le=
ft; text-decoration: none; text-indent: 0px; text-transform: none; -webkit-=
text-stroke-width: 0px; white-space: normal; word-spacing: 0px;">=C2=A0</di=
v><div style=3D"background-color: transparent; border-bottom-color: rgb(34,=
34, 34); border-bottom-style: none; border-bottom-width: 0px; border-image=
-outset: 0; border-image-repeat: stretch; border-image-slice: 100%; border-=
image-source: none; border-image-width: 1; border-left-color: rgb(34, 34, 3=
4); border-left-style: none; border-left-width: 0px; border-right-color: rg=
b(34, 34, 34); border-right-style: none; border-right-width: 0px; border-to=
p-color: rgb(34, 34, 34); border-top-style: none; border-top-width: 0px; co=
lor: rgb(34, 34, 34); font-family: &quot;Arial&quot;,&quot;Helv=
etica&quot;,sans-serif; font-size: 13px; font-style: normal; font-varia=
nt: normal; font-weight: 400; letter-spacing: normal; margin-bottom: 0px; m=
argin-left: 0px; margin-right: 0px; margin-top: 0px; orphans: 2; padding-bo=
ttom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-al=
ign: left; text-decoration: none; text-indent: 0px; text-transform: none; -=
webkit-text-stroke-width: 0px; white-space: normal; word-spacing: 0px;"><br=
></div></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/dd179d10-670c-4406-898f-203d22dea8c4%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/dd179d10-670c-4406-898f-203d22dea8c4=
%40isocpp.org</a>.<br />
------=_Part_9903_1421648621.1532595274019--
------=_Part_9902_276144743.1532595274019--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Thu, 26 Jul 2018 10:49:33 -0700 (PDT)
Raw View
------=_Part_5265_11546532.1532627373593
Content-Type: multipart/alternative;
boundary="----=_Part_5266_787370747.1532627373593"
------=_Part_5266_787370747.1532627373593
Content-Type: text/plain; charset="UTF-8"
>
>
> Niall, how does 1029 envisions moving multiple (contiguous) objects? It
> seems only object-by-object relocation is optimized "out of the box"?
>
> P1029 is deliberately as minimum as feasibly possible.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/051b2429-6c28-4878-a059-f3bcffd06e30%40isocpp.org.
------=_Part_5266_787370747.1532627373593
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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><span><div><br></div><div>Niall, how does 1029 envisions movi=
ng multiple (contiguous) objects? It seems only object-by-object relocation=
is optimized "out of the box"?</div><div><br></div></span></div>=
</div></div></blockquote><div>P1029 is deliberately as minimum as feasibly =
possible.</div><div><br></div><div>Niall=C2=A0</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/051b2429-6c28-4878-a059-f3bcffd06e30%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/051b2429-6c28-4878-a059-f3bcffd06e30=
%40isocpp.org</a>.<br />
------=_Part_5266_787370747.1532627373593--
------=_Part_5265_11546532.1532627373593--
.
Author: bogdan <bogdan.iordanescu@gmail.com>
Date: Sun, 29 Jul 2018 10:45:59 -0700 (PDT)
Raw View
------=_Part_10720_1147107879.1532886359900
Content-Type: multipart/alternative;
boundary="----=_Part_10721_2045140172.1532886359900"
------=_Part_10721_2045140172.1532886359900
Content-Type: text/plain; charset="UTF-8"
On Wednesday, July 25, 2018 at 11:53:02 AM UTC+3, Niall Douglas wrote:
>
>
> No, it's far more fundamental than that.
>
> Mapped memory enables three new things:
>
> 1. Object lifetime can now exceed that of the program. This has
> obvious difficulties wrt the current standard.
> 2. Objects can exist in multiple, concurrent instances of a C++
> program. The current standard assumes there can only be one C++ program.
> 3. The same object can have multiple addresses in a C++ program, and
> it is a hard assumption in the current standard that this is impossible.
>
>
Here are a few thoughts on the points above, hopefully not completely off
the mark.
1. Does it really need to? We already have objects whose value is
maintained across program restarts: zero-initialized static const objects.
The implementation ensures that every time the program is started those
objects spring up into existence having the same value they had in a
previous run. Yeah, it's always the same value, of course it's not the same
thing as persistent storage, but still, nobody is seeing those as the same
object that survives program restarts. Every time, a new object is created
in special storage. Couldn't the same model be used here?
2. and 3. I don't think these need to be the same object either. What if
they're all different objects created in special storage? All these objects
have the property that any access to one object is automagically reflected
in accesses to all the other objects sharing the same underlying mapped
storage. We already have objects for which any access results in
side-effects: volatile ones. Hold on, hold on, inspiration coming... const,
volatile, ... wormhole! Nah, maybe this shouldn't be a qualifier on the
object type; I'd see it more as a property of the storage. After all, why
not be able to map the same bytes at different addresses or in different
processes and create objects of different types in that storage?
/end of ramblings
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/87b75923-0ee3-41e2-be17-7ab258fb931b%40isocpp.org.
------=_Part_10721_2045140172.1532886359900
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Wednesday, July 25, 2018 at 11:53:02 AM UTC+3, Nial=
l Douglas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><br><div>No, i=
t's far more fundamental than that.</div><div><br></div><div>Mapped mem=
ory enables three new things:</div><div><ol><li>Object lifetime can now exc=
eed that of the program. This has obvious difficulties wrt the current stan=
dard.</li><li>Objects can exist in multiple, concurrent instances of a C++ =
program. The current standard assumes there can only be one C++ program.</l=
i><li>The same object can have multiple addresses in a C++ program, and it =
is a hard assumption in the current standard that this is impossible.</li><=
/ol></div></blockquote><div><br></div><div>Here are a few thoughts on the p=
oints above, hopefully not completely off the mark.</div><div><br></div><di=
v>1. Does it really need to? We already have objects whose value is maintai=
ned across program restarts: zero-initialized <span style=3D"font-family: c=
ourier new, monospace;">static const</span> objects. The implementation ens=
ures that every time the program is started those objects spring up into ex=
istence having the same value they had in a previous run. Yeah, it's al=
ways the same value, of course it's not the same thing as persistent st=
orage, but still, nobody is seeing those as the same object that survives p=
rogram restarts. Every time, a new object is created in special storage. Co=
uldn't the same model be used here?</div><div><br></div><div>2. and 3. =
I don't think these need to be the same object either. What if they'=
;re all different objects created in special storage? All these objects hav=
e the property that any access to one object is automagically reflected in =
accesses to all the other objects sharing the same underlying mapped storag=
e. We already have objects for which any access results in side-effects: <s=
pan style=3D"font-family: courier new, monospace;">volatile</span> ones. Ho=
ld on, hold on, inspiration coming... <span style=3D"font-family: courier n=
ew, monospace;">const</span>, <span style=3D"font-family: courier new, mono=
space;">volatile</span>, ... <span style=3D"font-family: courier new, monos=
pace;">wormhole</span>! Nah, maybe this shouldn't be a qualifier on the=
object type; I'd see it more as a property of the storage. After all, =
why not be able to map the same bytes at different addresses or in differen=
t processes and create objects of different types in that storage?<br></div=
><div><br></div><div>/end of ramblings<br></div><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/87b75923-0ee3-41e2-be17-7ab258fb931b%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/87b75923-0ee3-41e2-be17-7ab258fb931b=
%40isocpp.org</a>.<br />
------=_Part_10721_2045140172.1532886359900--
------=_Part_10720_1147107879.1532886359900--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Sun, 29 Jul 2018 10:57:34 -0700 (PDT)
Raw View
------=_Part_11083_1960680226.1532887054986
Content-Type: multipart/alternative;
boundary="----=_Part_11084_20658773.1532887054986"
------=_Part_11084_20658773.1532887054986
Content-Type: text/plain; charset="UTF-8"
>
> Mapped memory enables three new things:
>>
>> 1. Object lifetime can now exceed that of the program. This has
>> obvious difficulties wrt the current standard.
>> 2. Objects can exist in multiple, concurrent instances of a C++
>> program. The current standard assumes there can only be one C++ program.
>> 3. The same object can have multiple addresses in a C++ program, and
>> it is a hard assumption in the current standard that this is impossible.
>>
>>
> Here are a few thoughts on the points above, hopefully not completely off
> the mark.
>
Even the most expert of the experts on the committee will freely admit they
are unsure how best to proceed (if at all) with this. So ramble away!
>
> 1. Does it really need to? We already have objects whose value is
> maintained across program restarts: zero-initialized static const
> objects. The implementation ensures that every time the program is started
> those objects spring up into existence having the same value they had in a
> previous run. Yeah, it's always the same value, of course it's not the same
> thing as persistent storage, but still, nobody is seeing those as the same
> object that survives program restarts. Every time, a new object is created
> in special storage. Couldn't the same model be used here?
>
I currently do not believe so. The problem is that modifying an object
isn't as simple as just writing to its storage, you've also got to tell its
storage that all writes up until now constitute the object, and that writes
after must not be reordered earlier.
This form of write barrier is a third type of barrier in addition to the
compiler write barrier and the CPU write barrier. I don't believe it can be
avoided.
>
> 2. and 3. I don't think these need to be the same object either.
>
I don't think, in practice, that they will be the same object. An object
has a strict meaning in the current C++ object model: there is exactly one
of that type of object living at a unique address. So, changing its address
means it's a new object.
The approach I am currently taking is that you can bless and unbless
objects, and only one storage for an object can be blessed at a time,
otherwise it's UB.
This is conservative, but it should allow current alias optimisation to not
require a complete refactor.
Niall
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/41643247-25d2-4a59-bc2f-1cf5e0e64064%40isocpp.org.
------=_Part_11084_20658773.1532887054986
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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"><blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div>Mapped memory enables thre=
e new things:</div><div><ol><li>Object lifetime can now exceed that of the =
program. This has obvious difficulties wrt the current standard.</li><li>Ob=
jects can exist in multiple, concurrent instances of a C++ program. The cur=
rent standard assumes there can only be one C++ program.</li><li>The same o=
bject can have multiple addresses in a C++ program, and it is a hard assump=
tion in the current standard that this is impossible.</li></ol></div></bloc=
kquote><div><br></div><div>Here are a few thoughts on the points above, hop=
efully not completely off the mark.</div></div></blockquote><div><br></div>=
<div>Even the most expert of the experts on the committee will freely admit=
they are unsure how best to proceed (if at all) with this. So ramble away!=
</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div di=
r=3D"ltr"><div><br></div><div>1. Does it really need to? We already have ob=
jects whose value is maintained across program restarts: zero-initialized <=
span style=3D"font-family:courier new,monospace">static const</span> object=
s. The implementation ensures that every time the program is started those =
objects spring up into existence having the same value they had in a previo=
us run. Yeah, it's always the same value, of course it's not the sa=
me thing as persistent storage, but still, nobody is seeing those as the sa=
me object that survives program restarts. Every time, a new object is creat=
ed in special storage. Couldn't the same model be used here?</div></div=
></blockquote><div><br></div><div>I currently do not believe so. The proble=
m is that modifying an object isn't as simple as just writing to its st=
orage, you've also got to tell its storage that all writes up until now=
constitute the object, and that writes after must not be reordered earlier=
..</div><div><br></div><div>This form of write barrier is a third type of ba=
rrier in addition to the compiler write barrier and the CPU write barrier. =
I don't believe it can be avoided.</div><div>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><br></div><div>2. and =
3. I don't think these need to be the same object either.</div></div></=
blockquote><div><br></div><div>I don't think, in practice, that they wi=
ll be the same object. An object has a strict meaning in the current C++ ob=
ject model: there is exactly one of that type of object living at a unique =
address. So, changing its address means it's a new object.</div><div><b=
r></div><div>The approach I am currently taking is that you can bless and u=
nbless objects, and only one storage for an object can be blessed at a time=
, otherwise it's UB.</div><div><br></div><div>This is conservative, but=
it should allow current alias optimisation to not require a complete refac=
tor.</div><div><br></div><div>Niall</div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/41643247-25d2-4a59-bc2f-1cf5e0e64064%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/41643247-25d2-4a59-bc2f-1cf5e0e64064=
%40isocpp.org</a>.<br />
------=_Part_11084_20658773.1532887054986--
------=_Part_11083_1960680226.1532887054986--
.
Author: bogdan <bogdan.iordanescu@gmail.com>
Date: Sun, 29 Jul 2018 13:33:52 -0700 (PDT)
Raw View
------=_Part_11222_1174705767.1532896432968
Content-Type: multipart/alternative;
boundary="----=_Part_11223_885049296.1532896432968"
------=_Part_11223_885049296.1532896432968
Content-Type: text/plain; charset="UTF-8"
On Sunday, July 29, 2018 at 8:57:35 PM UTC+3, Niall Douglas wrote:
>
>
>>
>> 1. Does it really need to? We already have objects whose value is
>> maintained across program restarts: zero-initialized static const
>> objects. The implementation ensures that every time the program is started
>> those objects spring up into existence having the same value they had in a
>> previous run. Yeah, it's always the same value, of course it's not the same
>> thing as persistent storage, but still, nobody is seeing those as the same
>> object that survives program restarts. Every time, a new object is created
>> in special storage. Couldn't the same model be used here?
>>
>
> I currently do not believe so. The problem is that modifying an object
> isn't as simple as just writing to its storage, you've also got to tell its
> storage that all writes up until now constitute the object, and that writes
> after must not be reordered earlier.
>
> This form of write barrier is a third type of barrier in addition to the
> compiler write barrier and the CPU write barrier. I don't believe it can be
> avoided.
>
Was that a "no" to the first question or to the last question?
By "the same model" I didn't mean that it would be as easy as "let's make
sure this is set to 0", it's clearly more complicated than that. I was
referring to the fundamental property of lifetime and the object model,
basically that we're not talking about the same object between different
program runs, but a new object initialized to the right value. In other
words, it's the storage that's persistent, not the object.
> 2. and 3. I don't think these need to be the same object either.
>>
>
> I don't think, in practice, that they will be the same object. An object
> has a strict meaning in the current C++ object model: there is exactly one
> of that type of object living at a unique address. So, changing its address
> means it's a new object.
>
> The approach I am currently taking is that you can bless and unbless
> objects, and only one storage for an object can be blessed at a time,
> otherwise it's UB.
>
> This is conservative, but it should allow current alias optimisation to
> not require a complete refactor.
>
Sounds good to me.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/c4e5f27f-f974-4c99-b19e-c62a96f4f32a%40isocpp.org.
------=_Part_11223_885049296.1532896432968
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Sunday, July 29, 2018 at 8:57:35 PM UTC+3, Niall Do=
uglas 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">=
=C2=A0<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>1. Does=
it really need to? We already have objects whose value is maintained acros=
s program restarts: zero-initialized <span style=3D"font-family:courier new=
,monospace">static const</span> objects. The implementation ensures that ev=
ery time the program is started those objects spring up into existence havi=
ng the same value they had in a previous run. Yeah, it's always the sam=
e value, of course it's not the same thing as persistent storage, but s=
till, nobody is seeing those as the same object that survives program resta=
rts. Every time, a new object is created in special storage. Couldn't t=
he same model be used here?</div></div></blockquote><div><br></div><div>I c=
urrently do not believe so. The problem is that modifying an object isn'=
;t as simple as just writing to its storage, you've also got to tell it=
s storage that all writes up until now constitute the object, and that writ=
es after must not be reordered earlier.</div><div><br></div><div>This form =
of write barrier is a third type of barrier in addition to the compiler wri=
te barrier and the CPU write barrier. I don't believe it can be avoided=
.. <br></div></div></blockquote><div><br></div><div><br></div><div>Was that =
a "no" to the first question or to the last question?<br><br>By &=
quot;the same model" I didn't mean that it would be as easy as &qu=
ot;let's make sure this is set to 0", it's clearly more compli=
cated than that. I was referring to the fundamental property of lifetime an=
d the object model, basically that we're not talking about the same obj=
ect between different program runs, but a new object initialized to the rig=
ht value. In other words, it's the storage that's persistent, not t=
he object.<br></div><div><br></div><div>=C2=A0</div><blockquote class=3D"gm=
ail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc soli=
d;padding-left: 1ex;"><div dir=3D"ltr"><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr"><div>2. and 3. I don't think these need to be the =
same object either.</div></div></blockquote><div><br></div><div>I don't=
think, in practice, that they will be the same object. An object has a str=
ict meaning in the current C++ object model: there is exactly one of that t=
ype of object living at a unique address. So, changing its address means it=
's a new object.</div><div><br></div><div>The approach I am currently t=
aking is that you can bless and unbless objects, and only one storage for a=
n object can be blessed at a time, otherwise it's UB.</div><div><br></d=
iv><div>This is conservative, but it should allow current alias optimisatio=
n to not require a complete refactor.</div></div></blockquote><br><div><br>=
</div><div>Sounds good to me.</div><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/c4e5f27f-f974-4c99-b19e-c62a96f4f32a%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/c4e5f27f-f974-4c99-b19e-c62a96f4f32a=
%40isocpp.org</a>.<br />
------=_Part_11223_885049296.1532896432968--
------=_Part_11222_1174705767.1532896432968--
.
Author: "Arthur O'Dwyer" <arthur.j.odwyer@gmail.com>
Date: Sun, 29 Jul 2018 13:47:08 -0700
Raw View
--000000000000d75f16057229725d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Sun, Jul 29, 2018 at 10:45 AM, bogdan <bogdan.iordanescu@gmail.com>
wrote:
> On Wednesday, July 25, 2018 at 11:53:02 AM UTC+3, Niall Douglas wrote:
>>
>>
>> No, it's far more fundamental than that.
>>
>> Mapped memory enables three new things:
>>
>> 1. Object lifetime can now exceed that of the program. This has
>> obvious difficulties wrt the current standard.
>> 2. Objects can exist in multiple, concurrent instances of a C++
>> program. The current standard assumes there can only be one C++ progr=
am.
>> 3. The same object can have multiple addresses in a C++ program, and
>> it is a hard assumption in the current standard that this is impossib=
le.
>>
>>
> Here are a few thoughts on the points above, hopefully not completely off
> the mark.
>
> 1. Does it really need to? We already have objects whose value is
> maintained across program restarts: zero-initialized static const
> objects. The implementation ensures that every time the program is starte=
d
> those objects spring up into existence having the same value they had in =
a
> previous run. Yeah, it's always the same value, of course it's not the sa=
me
> thing as persistent storage, but still, nobody is seeing those as the sam=
e
> object that survives program restarts. Every time, a new object is create=
d
> in special storage. Couldn't the same model be used here?
>
> 2. and 3. I don't think these need to be the same object either. What if
> they're all different objects created in special storage? All these objec=
ts
> have the property that any access to one object is automagically reflecte=
d
> in accesses to all the other objects sharing the same underlying mapped
> storage. We already have objects for which any access results in
> side-effects: volatile ones. Hold on, hold on, inspiration coming... cons=
t,
> volatile, ... wormhole! Nah, maybe this shouldn't be a qualifier on the
> object type; I'd see it more as a property of the storage. After all, why
> not be able to map the same bytes at different addresses or in different
> processes and create objects of different types in that storage?
>
JF Bastien recently showed me a post by Linus Torvalds with which I tend to
agree:
https://gcc.gnu.org/ml/gcc/2012-02/msg00027.html
The traditional C "volatile" is misdesigned and wrong. We don't
generally mark data volatile, we really mark *code* volatile - which
is why our "volatiles" are in the casts, not on the data structures.
Stuff that is "volatile" in one context is not volatile in another. If
you hold a RCU write lock, it may well be entirely stable, and marking
it volatile is *wrong*, and generating code as if it was volatile is
pure and utter shit.
On the other hand, if you are touching *the*very*same* field while you
are only read-locked for RCU, it may well be one of those "this has to
be read by accessing it exactly once".
And we do all this correctly in the kernel. Modulo bugs, of course,
but the fundamental rule really is: "atomicity or volatility is about
CODE, not DATA".
[...] If you ever try to mark state, you've already lost. The same
"state" can be atomic or not depending on context. It's not about the
state or the data structures, and it never will be.
I don't know to what extent this applies to Niall's persistent-data stuff.
I believe it applies pretty darn well to "volatile". I believe it applies
enough to std::atomic that I have used "reinterpret_cast to atomic<int>*"
in at least one case (when I need to manipulate an int that someone else is
treating as a Linux futex); but at the same time it fails to apply in many
many cases (I do think atomic<int> is useful on its own).
Anyway, food for thought.
=E2=80=93Arthur
--=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/CADvuK0Laq%2B1fmFsB7nFYWMQJNwN_e6CnGoUc%3DJ6J1qG=
pWh%3DG3w%40mail.gmail.com.
--000000000000d75f16057229725d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Sun, Jul 29, 2018 at 10:45 AM, bogdan <span dir=3D"ltr"=
><<a href=3D"mailto:bogdan.iordanescu@gmail.com" target=3D"_blank">bogda=
n.iordanescu@gmail.com</a>></span> wrote:<br><div class=3D"gmail_extra">=
<div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margi=
n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-le=
ft-color:rgb(204,204,204);padding-left:1ex"><div dir=3D"ltr"><span class=3D=
"gmail-">On Wednesday, July 25, 2018 at 11:53:02 AM UTC+3, Niall Douglas wr=
ote:<blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;bor=
der-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,20=
4);padding-left:1ex"><br><div>No, it's far more fundamental than that.<=
/div><div><br></div><div>Mapped memory enables three new things:</div><div>=
<ol><li>Object lifetime can now exceed that of the program. This has obviou=
s difficulties wrt the current standard.</li><li>Objects can exist in multi=
ple, concurrent instances of a C++ program. The current standard assumes th=
ere can only be one C++ program.</li><li>The same object can have multiple =
addresses in a C++ program, and it is a hard assumption in the current stan=
dard that this is impossible.</li></ol></div></blockquote><div><br></div></=
span><div>Here are a few thoughts on the points above, hopefully not comple=
tely off the mark.</div><div><br></div><div>1. Does it really need to? We a=
lready have objects whose value is maintained across program restarts: zero=
-initialized <span style=3D"font-family:"courier new",monospace">=
static const</span> objects. The implementation ensures that every time the=
program is started those objects spring up into existence having the same =
value they had in a previous run. Yeah, it's always the same value, of =
course it's not the same thing as persistent storage, but still, nobody=
is seeing those as the same object that survives program restarts. Every t=
ime, a new object is created in special storage. Couldn't the same mode=
l be used here?</div><div><br></div><div>2. and 3. I don't think these =
need to be the same object either. What if they're all different object=
s created in special storage? All these objects have the property that any =
access to one object is automagically reflected in accesses to all the othe=
r objects sharing the same underlying mapped storage. We already have objec=
ts for which any access results in side-effects: <span style=3D"font-family=
:"courier new",monospace">volatile</span> ones. Hold on, hold on,=
inspiration coming... <span style=3D"font-family:"courier new",m=
onospace">const</span>, <span style=3D"font-family:"courier new",=
monospace">volatile</span>, ... <span style=3D"font-family:"courier ne=
w",monospace">wormhole</span>! Nah, maybe this shouldn't be a qual=
ifier on the object type; I'd see it more as a property of the storage.=
After all, why not be able to map the same bytes at different addresses or=
in different processes and create objects of different types in that stora=
ge?</div></div></blockquote><div><br></div><div>JF Bastien recently showed =
me a post by Linus Torvalds with which I tend to agree:</div><div><a href=
=3D"https://gcc.gnu.org/ml/gcc/2012-02/msg00027.html">https://gcc.gnu.org/m=
l/gcc/2012-02/msg00027.html</a></div><div><pre style=3D"color:rgb(0,0,0)">T=
he traditional C "volatile" is misdesigned and wrong. We don'=
t
generally mark data volatile, we really mark *code* volatile - which
is why our "volatiles" are in the casts, not on the data structur=
es.
Stuff that is "volatile" in one context is not volatile in anothe=
r. If
you hold a RCU write lock, it may well be entirely stable, and marking
it volatile is *wrong*, and generating code as if it was volatile is
pure and utter shit.
On the other hand, if you are touching *the*very*same* field while you
are only read-locked for RCU, it may well be one of those "this has to
be read by accessing it exactly once".
And we do all this correctly in the kernel. Modulo bugs, of course,
but the fundamental rule really is: "atomicity or volatility is about
CODE, not DATA".
</pre></div><div><pre style=3D"color:rgb(0,0,0)"><font face=3D"-webkit-stan=
dard"><span style=3D"white-space:normal">[...]=C2=A0</span></font>If you ev=
er try to mark state, you've already lost. The same
"state" can be atomic or not depending on context. It's not a=
bout the
state or the data structures, and it never will be.</pre></div><div>I don&#=
39;t know to what extent this applies to Niall's persistent-data stuff.=
I believe it applies pretty darn well to "volatile". I believe i=
t applies enough to std::atomic that I have used "reinterpret_cast to =
atomic<int>*" in at least one case (when I need to manipulate an=
int that someone else is treating as a Linux futex); but at the same time =
it fails to apply in many many cases (I do think atomic<int> is usefu=
l on its own).</div><div>Anyway, food for thought.</div><div><br></div><div=
>=E2=80=93Arthur</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" 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/CADvuK0Laq%2B1fmFsB7nFYWMQJNwN_e6CnGo=
Uc%3DJ6J1qGpWh%3DG3w%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CADvuK0Laq%=
2B1fmFsB7nFYWMQJNwN_e6CnGoUc%3DJ6J1qGpWh%3DG3w%40mail.gmail.com</a>.<br />
--000000000000d75f16057229725d--
.
Author: bogdan <bogdan.iordanescu@gmail.com>
Date: Tue, 31 Jul 2018 12:09:23 -0700 (PDT)
Raw View
------=_Part_11726_1070952664.1533064163094
Content-Type: multipart/alternative;
boundary="----=_Part_11727_1323381354.1533064163095"
------=_Part_11727_1323381354.1533064163095
Content-Type: text/plain; charset="UTF-8"
On Sunday, July 29, 2018 at 11:47:12 PM UTC+3, Arthur O'Dwyer wrote:
>
>
> JF Bastien recently showed me a post by Linus Torvalds with which I tend
> to agree:
> https://gcc.gnu.org/ml/gcc/2012-02/msg00027.html
>
> The traditional C "volatile" is misdesigned and wrong. We don't
> generally mark data volatile, we really mark *code* volatile - which
> is why our "volatiles" are in the casts, not on the data structures.
>
> Stuff that is "volatile" in one context is not volatile in another. [...]
>
>
Oh, the poor dear `volatile`, so misdesigned and so wrong... Ah, the
drama...
If a variable is `volatile` because its storage is actually used for
memory-mapped I/O, I'd say that variable will be `volatile` in all contexts.
I don't know to what extent this applies to Niall's persistent-data stuff.
> I believe it applies pretty darn well to "volatile". I believe it applies
> enough to std::atomic that I have used "reinterpret_cast to atomic<int>*"
> in at least one case (when I need to manipulate an int that someone else is
> treating as a Linux futex); but at the same time it fails to apply in many
> many cases (I do think atomic<int> is useful on its own).
> Anyway, food for thought.
>
The more I think about it, the clearer it becomes that I can't actually
form an opinion on whether a qualifier would make sense on the types of
variables whose storage is a mapped file.
But I tend to think that being part of a memory-mapped file is a property
of the storage first and foremost. Of course it reflects on the code using
that storage, types do that, but I wouldn't see it as code-first.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6550382e-ed5e-45fa-9a71-de4e546f0686%40isocpp.org.
------=_Part_11727_1323381354.1533064163095
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br>On Sunday, July 29, 2018 at 11:47:12 PM UTC+3, Arthur =
O'Dwyer wrote:<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"><br><div>JF Bastien recently showed me=
a post by Linus Torvalds with which I tend to agree:</div><div><a href=3D"=
https://gcc.gnu.org/ml/gcc/2012-02/msg00027.html" target=3D"_blank" rel=3D"=
nofollow" onmousedown=3D"this.href=3D'https://www.google.com/url?q\x3dh=
ttps%3A%2F%2Fgcc.gnu.org%2Fml%2Fgcc%2F2012-02%2Fmsg00027.html\x26sa\x3dD\x2=
6sntz\x3d1\x26usg\x3dAFQjCNHsWC2Qb4UsfRuw54R0Wn9IQZMhdg';return true;" =
onclick=3D"this.href=3D'https://www.google.com/url?q\x3dhttps%3A%2F%2Fg=
cc.gnu.org%2Fml%2Fgcc%2F2012-02%2Fmsg00027.html\x26sa\x3dD\x26sntz\x3d1\x26=
usg\x3dAFQjCNHsWC2Qb4UsfRuw54R0Wn9IQZMhdg';return true;">https://gcc.gn=
u.org/ml/gcc/<wbr>2012-02/msg00027.html</a></div><div><pre style=3D"color:r=
gb(0,0,0)">The traditional C "volatile" is misdesigned and wrong.=
We don't
generally mark data volatile, we really mark *code* volatile - which
is why our "volatiles" are in the casts, not on the data structur=
es.
Stuff that is "volatile" in one context is not volatile in anothe=
r. [...]</pre></div></div></div></div></blockquote><div><br></div><div>Oh, =
the poor dear `volatile`, so misdesigned and so wrong... Ah, the drama...<b=
r></div><div><br></div><div>If a variable is `volatile` because its storage=
is actually used for memory-mapped I/O, I'd say that variable will be =
`volatile` in all contexts.<br></div><div><br></div><div><pre style=3D"colo=
r:rgb(0,0,0)"></pre></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">I don't know to what exten=
t this applies to Niall's persistent-data stuff. I believe it applies p=
retty darn well to "volatile". I believe it applies enough to std=
::atomic that I have used "reinterpret_cast to atomic<int>*"=
; in at least one case (when I need to manipulate an int that someone else =
is treating as a Linux futex); but at the same time it fails to apply in ma=
ny many cases (I do think atomic<int> is useful on its own).<div>Anyw=
ay, food for thought.</div></div></div></div></blockquote><div><br></div><d=
iv>The more I think about it, the clearer it becomes that I can't actua=
lly form an opinion on whether a qualifier would make sense on the types of=
variables whose storage is a mapped file. <br></div><div><br></div><div>Bu=
t I tend to think that being part of a memory-mapped file is a property of =
the storage first and foremost. Of course it reflects on the code using tha=
t storage, types do that, but I wouldn't see it as code-first. <br></di=
v><div><br></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/6550382e-ed5e-45fa-9a71-de4e546f0686%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6550382e-ed5e-45fa-9a71-de4e546f0686=
%40isocpp.org</a>.<br />
------=_Part_11727_1323381354.1533064163095--
------=_Part_11726_1070952664.1533064163094--
.
Author: Niall Douglas <nialldouglas14@gmail.com>
Date: Tue, 31 Jul 2018 12:37:25 -0700 (PDT)
Raw View
------=_Part_11574_1461593650.1533065845472
Content-Type: multipart/alternative;
boundary="----=_Part_11575_389896972.1533065845472"
------=_Part_11575_389896972.1533065845472
Content-Type: text/plain; charset="UTF-8"
>
>
> But I tend to think that being part of a memory-mapped file is a property
> of the storage first and foremost. Of course it reflects on the code using
> that storage, types do that, but I wouldn't see it as code-first.
>
> Exactly what I have proposed
at https://groups.google.com/a/isocpp.org/forum/#!topic/std-proposals/bk8esqk-Qoo!
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/7b014241-6b71-4511-bf53-e9701cb276ef%40isocpp.org.
------=_Part_11575_389896972.1533065845472
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><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><br></div><div>But I tend to think that being part of a memory-map=
ped file is a property of the storage first and foremost. Of course it refl=
ects on the code using that storage, types do that, but I wouldn't see =
it as code-first. <br></div><div><br></div></div></blockquote><div>Exactly =
what I have proposed at=C2=A0https://groups.google.com/a/isocpp.org/forum/#=
!topic/std-proposals/bk8esqk-Qoo!</div><div>=C2=A0<br></div></div>
<p></p>
-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/7b014241-6b71-4511-bf53-e9701cb276ef%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/7b014241-6b71-4511-bf53-e9701cb276ef=
%40isocpp.org</a>.<br />
------=_Part_11575_389896972.1533065845472--
------=_Part_11574_1461593650.1533065845472--
.