Topic: Carefully State Effects of list::splice Function


Author: arseny.klimovsky@gmail.com
Date: Wed, 14 Aug 2013 14:32:18 -0700 (PDT)
Raw View
------=_Part_2878_8358483.1376515938015
Content-Type: text/plain; charset=ISO-8859-1

I think that the effects of list::splice function should be stated more
carefully.

Function transferring a single element is described now in the following
way (N3485 23.3.5.5/7):

void splice(const_iterator position, list& x, const_iterator i);
void splice(const_iterator position, list&& x, const_iterator i);

*Effects:* Inserts an element pointed to by i from list x before position
and removes the element from
x. The result is unchanged if position == i or position == ++i. Pointers
and references to *i
continue to refer to this same element but as a member of *this. Iterators
to *i (including i itself)
continue to refer to the same element, but now behave as iterators into
*this, not into x.

But it is incorrect to talk about operator == for iterators that are not
from the same container. This is not stated
in the standard, but it was discussed as issue 446 in N2948<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html>.
So, the text operates with undefined behaviour.

Motivation
One is formally allowed to have list implementation where two iterators
from different lists return true to operator ==.
For example, this can only happen to non-dereferenceable iterators, and
position and ++i can be non-dereferenceable.
So, literally according to the standard, it is not allowed in this
implementation to transfer such elements with splice function.

Proposal
State this point carefully:
The result is unchanged if* &x == this and* position == i or position == ++i
..

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_2878_8358483.1376515938015
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">I think that the effects of list::splice function should b=
e stated more carefully.<br><br>Function transferring a single element is d=
escribed now in the following way (N3485 23.3.5.5/7):<br><br><div style=3D"=
margin-left: 40px;"><span style=3D"font-family: courier new,monospace;">voi=
d splice(const_iterator position, list&amp; x, const_iterator i);</span><br=
><span style=3D"font-family: courier new,monospace;">void splice(const_iter=
ator position, list&amp;&amp; x, const_iterator i);</span><br><span style=
=3D"font-family: courier new,monospace;"></span><br><span style=3D"font-fam=
ily: courier new,monospace;"></span><i>Effects:</i> Inserts an element poin=
ted to by <span style=3D"font-family: courier new,monospace;">i</span> from=
 list <span style=3D"font-family: courier new,monospace;">x</span> before p=
osition and removes the element from<br><span style=3D"font-family: courier=
 new,monospace;">x</span>. The result is unchanged if <span style=3D"font-f=
amily: courier new,monospace;">position =3D=3D i</span> or <span style=3D"f=
ont-family: courier new,monospace;">position =3D=3D ++i</span>. Pointers an=
d references to <span style=3D"font-family: courier new,monospace;">*i</spa=
n><br>continue to refer to this same element but as a member of <span style=
=3D"font-family: courier new,monospace;">*this</span>. Iterators to <span s=
tyle=3D"font-family: courier new,monospace;">*i</span> (including <span sty=
le=3D"font-family: courier new,monospace;">i</span> itself)<br>continue to =
refer to the same element, but now behave as iterators into <span style=3D"=
font-family: courier new,monospace;">*this</span>, not into <span style=3D"=
font-family: courier new,monospace;">x</span>.<br></div><br>But it is incor=
rect to talk about <span style=3D"font-family: courier new,monospace;">oper=
ator =3D=3D</span> for iterators that are not from the same container. This=
 is not stated <br>in the standard, but it was discussed as issue 446 in <a=
 href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html=
">N2948</a>. So, the text operates with undefined behaviour.<br><br>Motivat=
ion<br>One is formally allowed to have list implementation where two iterat=
ors from different lists return <span style=3D"font-family: courier new,mon=
ospace;">true</span> to <span style=3D"font-family: courier new,monospace;"=
>operator =3D=3D</span>.<br>For example, this can only happen to non-derefe=
renceable iterators, and <span style=3D"font-family: courier new,monospace;=
">position<span style=3D"font-family: arial,sans-serif;"> and </span>++i<sp=
an style=3D"font-family: arial,sans-serif;"> can be </span></span><span sty=
le=3D"font-family: courier new,monospace;"><span style=3D"font-family: aria=
l,sans-serif;">non-dereferenceable</span></span>. <br>So, literally accordi=
ng to the standard, it is not allowed in this implementation to transfer su=
ch elements with splice function.<br><br>Proposal<br>State this point caref=
ully:<br><div style=3D"margin-left: 40px;">The result is unchanged if<u> <s=
pan style=3D"font-family: courier new,monospace;">&amp;x =3D=3D this</span>=
 and</u> <span style=3D"font-family: courier new,monospace;">position =3D=
=3D i</span> or <span style=3D"font-family: courier new,monospace;">positio=
n =3D=3D ++i</span>.<br></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_2878_8358483.1376515938015--

.


Author: Jonathan Wakely <cxx@kayari.org>
Date: Thu, 15 Aug 2013 03:42:33 -0700 (PDT)
Raw View
------=_Part_7_27701008.1376563353022
Content-Type: text/plain; charset=ISO-8859-1



On Wednesday, August 14, 2013 10:32:18 PM UTC+1, arseny.k...@gmail.com
wrote:
>
> I think that the effects of list::splice function should be stated more
> carefully.
>
> Function transferring a single element is described now in the following
> way (N3485 23.3.5.5/7):
>
> void splice(const_iterator position, list& x, const_iterator i);
> void splice(const_iterator position, list&& x, const_iterator i);
>
> *Effects:* Inserts an element pointed to by i from list x before position
> and removes the element from
> x. The result is unchanged if position == i or position == ++i. Pointers
> and references to *i
> continue to refer to this same element but as a member of *this.
> Iterators to *i (including i itself)
> continue to refer to the same element, but now behave as iterators into
> *this, not into x.
>
> But it is incorrect to talk about operator == for iterators that are not
> from the same container. This is not stated
> in the standard, but it was discussed as issue 446 in N2948<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2948.html>.
> So, the text operates with undefined behaviour.
>
> Motivation
> One is formally allowed to have list implementation where two iterators
> from different lists return true to operator ==.
> For example, this can only happen to non-dereferenceable iterators, and
> position and ++i can be non-dereferenceable.
> So, literally according to the standard, it is not allowed in this
> implementation to transfer such elements with splice function.
>
> Proposal
> State this point carefully:
> The result is unchanged if* &x == this and* position == i or position ==
> ++i.
>
>
This is really a defect report, not a proposal, so should be submitted as
described at http://cplusplus.github.io/LWG/lwg-active.html

My first thought is that in places we define algorithms in terms of
iterator operations that aren't even valid on all iterator categories, so
this isn't much worse.  The specification is not intended to be
transliterated directly to code, so it's implied that implementors should
not compare the iterators for equality if doing so would be UB.  Your
proposed change would clarify things though.

--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_7_27701008.1376563353022
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Wednesday, August 14, 2013 10:32:18 PM UTC+1, a=
rseny.k...@gmail.com wrote:<blockquote class=3D"gmail_quote" style=3D"margi=
n: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><di=
v dir=3D"ltr">I think that the effects of list::splice function should be s=
tated more carefully.<br><br>Function transferring a single element is desc=
ribed now in the following way (N3485 <a href=3D"http://23.3.5.5/7" target=
=3D"_blank">23.3.5.5/7</a>):<br><br><div style=3D"margin-left:40px"><span s=
tyle=3D"font-family:courier new,monospace">void splice(const_iterator posit=
ion, list&amp; x, const_iterator i);</span><br><span style=3D"font-family:c=
ourier new,monospace">void splice(const_iterator position, list&amp;&amp; x=
, const_iterator i);</span><br><span style=3D"font-family:courier new,monos=
pace"></span><br><span style=3D"font-family:courier new,monospace"></span><=
i>Effects:</i> Inserts an element pointed to by <span style=3D"font-family:=
courier new,monospace">i</span> from list <span style=3D"font-family:courie=
r new,monospace">x</span> before position and removes the element from<br><=
span style=3D"font-family:courier new,monospace">x</span>. The result is un=
changed if <span style=3D"font-family:courier new,monospace">position =3D=
=3D i</span> or <span style=3D"font-family:courier new,monospace">position =
=3D=3D ++i</span>. Pointers and references to <span style=3D"font-family:co=
urier new,monospace">*i</span><br>continue to refer to this same element bu=
t as a member of <span style=3D"font-family:courier new,monospace">*this</s=
pan>. Iterators to <span style=3D"font-family:courier new,monospace">*i</sp=
an> (including <span style=3D"font-family:courier new,monospace">i</span> i=
tself)<br>continue to refer to the same element, but now behave as iterator=
s into <span style=3D"font-family:courier new,monospace">*this</span>, not =
into <span style=3D"font-family:courier new,monospace">x</span>.<br></div><=
br>But it is incorrect to talk about <span style=3D"font-family:courier new=
,monospace">operator =3D=3D</span> for iterators that are not from the same=
 container. This is not stated <br>in the standard, but it was discussed as=
 issue 446 in <a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers=
/2009/n2948.html" target=3D"_blank">N2948</a>. So, the text operates with u=
ndefined behaviour.<br><br>Motivation<br>One is formally allowed to have li=
st implementation where two iterators from different lists return <span sty=
le=3D"font-family:courier new,monospace">true</span> to <span style=3D"font=
-family:courier new,monospace">operator =3D=3D</span>.<br>For example, this=
 can only happen to non-dereferenceable iterators, and <span style=3D"font-=
family:courier new,monospace">position<span style=3D"font-family:arial,sans=
-serif"> and </span>++i<span style=3D"font-family:arial,sans-serif"> can be=
 </span></span><span style=3D"font-family:courier new,monospace"><span styl=
e=3D"font-family:arial,sans-serif">non-dereferenceable</span></span>. <br>S=
o, literally according to the standard, it is not allowed in this implement=
ation to transfer such elements with splice function.<br><br>Proposal<br>St=
ate this point carefully:<br><div style=3D"margin-left:40px">The result is =
unchanged if<u> <span style=3D"font-family:courier new,monospace">&amp;x =
=3D=3D this</span> and</u> <span style=3D"font-family:courier new,monospace=
">position =3D=3D i</span> or <span style=3D"font-family:courier new,monosp=
ace">position =3D=3D ++i</span>.<br></div><br></div></blockquote><div><br>T=
his is really a defect report, not a proposal, so should be submitted as de=
scribed at http://cplusplus.github.io/LWG/lwg-active.html<br><br>My first t=
hought is that in places we define algorithms in terms of iterator operatio=
ns that aren't even valid on all iterator categories, so this isn't much wo=
rse.&nbsp; The specification is not intended to be transliterated directly =
to code, so it's implied that implementors should not compare the iterators=
 for equality if doing so would be UB.&nbsp; Your proposed change would cla=
rify things though.<br></div></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_7_27701008.1376563353022--

.