Topic: A pointer to type X can point to an object of


Author: Edward Catmur <ed@catmur.co.uk>
Date: Mon, 29 Aug 2016 14:43:52 -0700 (PDT)
Raw View
------=_Part_8_474496683.1472507032723
Content-Type: multipart/alternative;
 boundary="----=_Part_9_974195081.1472507032724"

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

On Sunday, 28 August 2016 10:58:56 UTC+1, Kazutoshi SATODA wrote:
>
> Given this example code:=20
>
>   struct X {...};=20
>   struct Y {...};=20
>   X oX;=20
>   Y oY;=20
>   X* pX =3D reinterpret_cast<X*>(&oY);=20
>
> P0137R1 (http://wg21.link/P0137R1) introduces possibilities where=20
> "pX points to oY" by reinterpret_cast like the above. A similar=20
> interpretation is shown in a recent discussion, and the author of=20
> P0137R1 agreed on.=20
>
> https://groups.google.com/a/isocpp.org/d/msg/std-discussion/XYvVlTc3-to/B=
9wdNcYzBAAJ=20
> On 2016/08/18 3:44 +0900, Kazutoshi Satoda wrote:=20
> > The result of reinterpret_cast<Base*>(&d), which is the value of pb, is=
=20
> > defined as static_cast<Base*>(static_cast<void*>(&d)) (in 5.2.10 p7),=
=20
> > and the both static_cast are defined as "the pointer value is unchanged=
=20
> > by the conversion" (4.11 p2, 5.2.9 p13) then the result points to d as=
=20
> > &d does.=20
>
> https://groups.google.com/a/isocpp.org/d/msg/std-discussion/XYvVlTc3-to/N=
5R0qoU7BAAJ=20
> On 2016/08/18 6:06 +0900, Richard Smith wrote:=20
> > The Base and Derived objects are not pointer-interconvertible, because=
=20
> > Derived is not a standard-layout class type. Therefore pb is a pointer=
=20
> > of type Base* that points to the d object, not to its Base subobject.=
=20
>
> Previous definition of "point to" in C++14 was:=20
> > ... If an object of type T is located at an address A, a pointer of=20
> > type cv T* whose value is the address A is said to point to that=20
> > object, regardless of how the value was obtained. ...=20
> Then, a pointer to type X could point to an object only of type X.=20
>
> I think the situation "pX points to oY" causes some problems:=20
>
>   - The semantics of "pX + 1"=20
>
>     5.7 [expr.add] p4 says:=20
>     > When an expression that has integral type is added to or subtracted=
=20
>     > from a pointer, the result has the type of the pointer operand. If=
=20
>     > the expression P points to element x[i] of an array object x with n=
=20
>     > elements, the expressions P + J and J + P (where J has the value j)=
=20
>     > point to the (possibly-hypothetical) element=20
>     > x[i + j] if 0 <=3D i + j <=3D n; otherwise, the behavior is undefin=
ed.=20
>     > Likewise, the expression P - J points to the (possibly-hypothetical=
)=20
>     > element x[i =E2=88=92 j] if 0 <=3D i =E2=88=92 j <=3D n; otherwise,=
 the behavior is=20
>     > undefined.=20
>
>     To fulfill this definition, pX + 1 must produce a pointer to type X=
=20
>     whose value is past the end of oY (note that a non-array object is=20
>     considered to be an array of 1 element here).=20
>     Producing such a value requires sizeof(Y) which compilers can't know=
=20
>     in general unless the type information is tracked at runtime.=20
>
>     Proposed resolution (edits by <ins> and <del>):=20
>       When an expression that has integral type is added to or subtracted=
=20
>       from a pointer <ins>to T</ins>, the result has the type of the=20
>       pointer operand. If the expression P points to element x[i] of an=
=20
>       array object x <del>with n elements</del><ins>of type T2[n] where=
=20
>       T2 is similar to T</ins>, ...=20
>
>     The resolution makes pX + 1 cause undefined behavior.=20
>

I think that [expr.add]/6 handles this, if a little clumsily:

> For addition or subtraction, if the expressions P or Q have type =E2=80=
=9Cpointer=20
to cv T=E2=80=9D, where T and the array
element type are not similar (4.4), the behavior is undefined.

It seems apparent that the "array element type" here is the runtime type Y=
=20
whereas T is X.

[expr.static.cast] handles this better for derived-base conversions (p2 and=
=20
p11); the use "actually" makes it clear that the runtime type is what=20
matters.

  - The semantics of "pX->...", along with "*pX"=20
>
>     5.2.5 [expr.ref] p2 says:=20
>     > For the first option (dot) the first expression shall have complete=
=20
>     > class type. For the second option (arrow) the first expression shal=
l=20
>     > have pointer to complete class type. The expression E1->E2 is=20
>     > converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5=
=20
>     > will address only the first option (dot). In either case, the=20
>     > id-expression shall name a member of the class or of one of its bas=
e=20
>     > classes. ...=20
>     and bullet (4.2) in p4 says:=20
>     > - If E2 is a non-static data member and the type of E1 is=20
>     >   "cq1 vq1 X", and the type of E2 is "cq2 vq2 T", the expression=20
>     >   designates the named member of the object designated by the first=
=20
>     >   expression.=20
>     As for (*(E1)), 5.3.1 [expr.unary.op] p1 says:=20
>     > The unary * operator performs indirection: the expression to which=
=20
>     > it is applied shall be a pointer to an object type, or a pointer to=
=20
>     > a function type and the result is an lvalue referring to the object=
=20
>     > or function to which the expression points. If the type of the=20
>     > expression is "pointer to T," the type of the result is "T."=20
>
>     *pX is an lvalue referring to oY, while the type of the expression=20
>     is X. Then E2 shall name a member of X, which might not name a=20
>     member of Y, that (for example) render the bullet (4.2) nonsense.=20
>

Agreed, that's pretty nasty.

    I think this adds another case to be handled by CWG issue #232.=20
>     "Is indirection through a null pointer undefined behavior?"=20
>     http://wg21.cmeerw.net/cwg/issue232=20
> <http://www.google.com/url?q=3Dhttp%3A%2F%2Fwg21.cmeerw.net%2Fcwg%2Fissue=
232&sa=3DD&sntz=3D1&usg=3DAFQjCNEQQh29NqvMp8Jx9_fOw85hOL3iEg>=20
>     (which is in "drafting" status for 10 years...)=20
>
> I suspect there are more problems like these.=20
>

[conv.lval]/1 would seem to be another one, also following=20
[expr.unary.op]/1.

I'll try to make these to be NB comments. Please correct me if the=20
> analysis are wrong. Ideas about the resolution are also welcome.=20
>

Tightening [expr.unary.op]/1 would probably deal with the majority of=20
cases, but might be viewed as too stringent (it's the old chestnut of=20
whether &*expr is equivalent to expr...) as with CWG 232.

Thanks for your work on this.

--=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/02ee460f-bf1f-461a-9dda-9f664e28fde0%40isocpp.or=
g.

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

<div dir=3D"ltr">On Sunday, 28 August 2016 10:58:56 UTC+1, Kazutoshi SATODA=
  wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0=
..8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Given this example cod=
e:
<br>
<br>=C2=A0 struct X {...};
<br>=C2=A0 struct Y {...};
<br>=C2=A0 X oX;
<br>=C2=A0 Y oY;
<br>=C2=A0 X* pX =3D reinterpret_cast&lt;X*&gt;(&amp;oY);
<br>
<br>P0137R1 (<a href=3D"http://wg21.link/P0137R1" target=3D"_blank" rel=3D"=
nofollow" onmousedown=3D"this.href=3D&#39;http://www.google.com/url?q\x3dht=
tp%3A%2F%2Fwg21.link%2FP0137R1\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFQMP=
fDNB_C0lVaNSHeOBUsZtdFkg&#39;;return true;" onclick=3D"this.href=3D&#39;htt=
p://www.google.com/url?q\x3dhttp%3A%2F%2Fwg21.link%2FP0137R1\x26sa\x3dD\x26=
sntz\x3d1\x26usg\x3dAFQjCNFQMPfDNB_C0lVaNSHeOBUsZtdFkg&#39;;return true;">h=
ttp://wg21.link/P0137R1</a>) introduces possibilities where
<br>&quot;pX points to oY&quot; by reinterpret_cast like the above. A simil=
ar
<br>interpretation is shown in a recent discussion, and the author of
<br>P0137R1 agreed on.
<br><a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-discussion/=
XYvVlTc3-to/B9wdNcYzBAAJ" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-discussi=
on/XYvVlTc3-to/B9wdNcYzBAAJ&#39;;return true;" onclick=3D"this.href=3D&#39;=
https://groups.google.com/a/isocpp.org/d/msg/std-discussion/XYvVlTc3-to/B9w=
dNcYzBAAJ&#39;;return true;">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>discussion/XYvVlTc3-to/<wbr>B9wdNcYzBAAJ</a>
<br>On 2016/08/18 3:44 +0900, Kazutoshi Satoda wrote:
<br>&gt; The result of reinterpret_cast&lt;Base*&gt;(&amp;d), which is the =
value of pb, is
<br>&gt; defined as static_cast&lt;Base*&gt;(static_<wbr>cast&lt;void*&gt;(=
&amp;d)) (in 5.2.10 p7),
<br>&gt; and the both static_cast are defined as &quot;the pointer value is=
 unchanged
<br>&gt; by the conversion&quot; (4.11 p2, 5.2.9 p13) then the result point=
s to d as
<br>&gt; &amp;d does.
<br><a href=3D"https://groups.google.com/a/isocpp.org/d/msg/std-discussion/=
XYvVlTc3-to/N5R0qoU7BAAJ" target=3D"_blank" rel=3D"nofollow" onmousedown=3D=
"this.href=3D&#39;https://groups.google.com/a/isocpp.org/d/msg/std-discussi=
on/XYvVlTc3-to/N5R0qoU7BAAJ&#39;;return true;" onclick=3D"this.href=3D&#39;=
https://groups.google.com/a/isocpp.org/d/msg/std-discussion/XYvVlTc3-to/N5R=
0qoU7BAAJ&#39;;return true;">https://groups.google.com/a/<wbr>isocpp.org/d/=
msg/std-<wbr>discussion/XYvVlTc3-to/<wbr>N5R0qoU7BAAJ</a>
<br>On 2016/08/18 6:06 +0900, Richard Smith wrote:
<br>&gt; The Base and Derived objects are not pointer-interconvertible, bec=
ause
<br>&gt; Derived is not a standard-layout class type. Therefore pb is a poi=
nter
<br>&gt; of type Base* that points to the d object, not to its Base subobje=
ct.
<br>
<br>Previous definition of &quot;point to&quot; in C++14 was:
<br>&gt; ... If an object of type T is located at an address A, a pointer o=
f
<br>&gt; type cv T* whose value is the address A is said to point to that
<br>&gt; object, regardless of how the value was obtained. ...
<br>Then, a pointer to type X could point to an object only of type X.
<br>
<br>I think the situation &quot;pX points to oY&quot; causes some problems:
<br>
<br>=C2=A0 - The semantics of &quot;pX + 1&quot;
<br>
<br>=C2=A0 =C2=A0 5.7 [expr.add] p4 says:
<br>=C2=A0 =C2=A0 &gt; When an expression that has integral type is added t=
o or subtracted
<br>=C2=A0 =C2=A0 &gt; from a pointer, the result has the type of the point=
er operand. If
<br>=C2=A0 =C2=A0 &gt; the expression P points to element x[i] of an array =
object x with n
<br>=C2=A0 =C2=A0 &gt; elements, the expressions P + J and J + P (where J h=
as the value j)
<br>=C2=A0 =C2=A0 &gt; point to the (possibly-hypothetical) element
<br>=C2=A0 =C2=A0 &gt; x[i + j] if 0 &lt;=3D i + j &lt;=3D n; otherwise, th=
e behavior is undefined.
<br>=C2=A0 =C2=A0 &gt; Likewise, the expression P - J points to the (possib=
ly-hypothetical)
<br>=C2=A0 =C2=A0 &gt; element x[i =E2=88=92 j] if 0 &lt;=3D i =E2=88=92 j =
&lt;=3D n; otherwise, the behavior is
<br>=C2=A0 =C2=A0 &gt; undefined.
<br>
<br>=C2=A0 =C2=A0 To fulfill this definition, pX + 1 must produce a pointer=
 to type X
<br>=C2=A0 =C2=A0 whose value is past the end of oY (note that a non-array =
object is
<br>=C2=A0 =C2=A0 considered to be an array of 1 element here).
<br>=C2=A0 =C2=A0 Producing such a value requires sizeof(Y) which compilers=
 can&#39;t know
<br>=C2=A0 =C2=A0 in general unless the type information is tracked at runt=
ime.
<br>
<br>=C2=A0 =C2=A0 Proposed resolution (edits by &lt;ins&gt; and &lt;del&gt;=
):
<br>=C2=A0 =C2=A0 =C2=A0 When an expression that has integral type is added=
 to or subtracted
<br>=C2=A0 =C2=A0 =C2=A0 from a pointer &lt;ins&gt;to T&lt;/ins&gt;, the re=
sult has the type of the
<br>=C2=A0 =C2=A0 =C2=A0 pointer operand. If the expression P points to ele=
ment x[i] of an
<br>=C2=A0 =C2=A0 =C2=A0 array object x &lt;del&gt;with n elements&lt;/del&=
gt;&lt;ins&gt;of type T2[n] where
<br>=C2=A0 =C2=A0 =C2=A0 T2 is similar to T&lt;/ins&gt;, ...
<br>
<br>=C2=A0 =C2=A0 The resolution makes pX + 1 cause undefined behavior.
<br></blockquote><div><br></div><div>I think that [expr.add]/6 handles this=
, if a little clumsily:</div><div><br></div><div>&gt; For addition or subtr=
action, if the expressions P or Q have type =E2=80=9Cpointer to cv T=E2=80=
=9D, where T and the array</div><div>element type are not similar (4.4), th=
e behavior is undefined.</div><div><br></div><div>It seems apparent that th=
e &quot;array element type&quot; here is the runtime type Y whereas T is X.=
</div><div><br></div><div>[expr.static.cast] handles this better for derive=
d-base conversions (p2 and p11); the use &quot;actually&quot; makes it clea=
r that the runtime type is what matters.</div><div><br></div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px =
#ccc solid;padding-left: 1ex;">=C2=A0 - The semantics of &quot;pX-&gt;...&q=
uot;, along with &quot;*pX&quot;
<br>
<br>=C2=A0 =C2=A0 5.2.5 [expr.ref] p2 says:
<br>=C2=A0 =C2=A0 &gt; For the first option (dot) the first expression shal=
l have complete
<br>=C2=A0 =C2=A0 &gt; class type. For the second option (arrow) the first =
expression shall
<br>=C2=A0 =C2=A0 &gt; have pointer to complete class type. The expression =
E1-&gt;E2 is
<br>=C2=A0 =C2=A0 &gt; converted to the equivalent form (*(E1)).E2; the rem=
ainder of 5.2.5
<br>=C2=A0 =C2=A0 &gt; will address only the first option (dot). In either =
case, the
<br>=C2=A0 =C2=A0 &gt; id-expression shall name a member of the class or of=
 one of its base
<br>=C2=A0 =C2=A0 &gt; classes. ...
<br>=C2=A0 =C2=A0 and bullet (4.2) in p4 says:
<br>=C2=A0 =C2=A0 &gt; - If E2 is a non-static data member and the type of =
E1 is
<br>=C2=A0 =C2=A0 &gt; =C2=A0 &quot;cq1 vq1 X&quot;, and the type of E2 is =
&quot;cq2 vq2 T&quot;, the expression
<br>=C2=A0 =C2=A0 &gt; =C2=A0 designates the named member of the object des=
ignated by the first
<br>=C2=A0 =C2=A0 &gt; =C2=A0 expression.
<br>=C2=A0 =C2=A0 As for (*(E1)), 5.3.1 [expr.unary.op] p1 says:
<br>=C2=A0 =C2=A0 &gt; The unary * operator performs indirection: the expre=
ssion to which
<br>=C2=A0 =C2=A0 &gt; it is applied shall be a pointer to an object type, =
or a pointer to
<br>=C2=A0 =C2=A0 &gt; a function type and the result is an lvalue referrin=
g to the object
<br>=C2=A0 =C2=A0 &gt; or function to which the expression points. If the t=
ype of the
<br>=C2=A0 =C2=A0 &gt; expression is &quot;pointer to T,&quot; the type of =
the result is &quot;T.&quot;
<br>
<br>=C2=A0 =C2=A0 *pX is an lvalue referring to oY, while the type of the e=
xpression
<br>=C2=A0 =C2=A0 is X. Then E2 shall name a member of X, which might not n=
ame a
<br>=C2=A0 =C2=A0 member of Y, that (for example) render the bullet (4.2) n=
onsense.
<br></blockquote><div><br></div><div>Agreed, that&#39;s pretty nasty.</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;">=C2=A0 =C2=A0 I=
 think this adds another case to be handled by CWG issue #232.
<br>=C2=A0 =C2=A0 &quot;Is indirection through a null pointer undefined beh=
avior?&quot;
<br>=C2=A0 =C2=A0 <a href=3D"http://www.google.com/url?q=3Dhttp%3A%2F%2Fwg2=
1.cmeerw.net%2Fcwg%2Fissue232&amp;sa=3DD&amp;sntz=3D1&amp;usg=3DAFQjCNEQQh2=
9NqvMp8Jx9_fOw85hOL3iEg" target=3D"_blank" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwg21.cmeerw.ne=
t%2Fcwg%2Fissue232\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEQQh29NqvMp8Jx9_=
fOw85hOL3iEg&#39;;return true;" onclick=3D"this.href=3D&#39;http://www.goog=
le.com/url?q\x3dhttp%3A%2F%2Fwg21.cmeerw.net%2Fcwg%2Fissue232\x26sa\x3dD\x2=
6sntz\x3d1\x26usg\x3dAFQjCNEQQh29NqvMp8Jx9_fOw85hOL3iEg&#39;;return true;">=
http://wg21.cmeerw.net/cwg/<wbr>issue232</a>
<br>=C2=A0 =C2=A0 (which is in &quot;drafting&quot; status for 10 years...)
<br>
<br>I suspect there are more problems like these.
<br></blockquote><div><br></div><div>[conv.lval]/1 would seem to be another=
 one, also following [expr.unary.op]/1.</div><div><br></div><blockquote cla=
ss=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #=
ccc solid;padding-left: 1ex;">I&#39;ll try to make these to be NB comments.=
 Please correct me if the
<br>analysis are wrong. Ideas about the resolution are also welcome.
<br></blockquote><div><br></div><div>Tightening [expr.unary.op]/1 would pro=
bably deal with the majority of cases, but might be viewed as too stringent=
 (it&#39;s the old chestnut of whether &amp;*expr is equivalent to expr...)=
 as with CWG 232.</div><div><br></div><div>Thanks for your work on this.</d=
iv></div>

<p></p>

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

------=_Part_9_974195081.1472507032724--

------=_Part_8_474496683.1472507032723--

.


Author: Kazutoshi Satoda <k_satoda@f2.dion.ne.jp>
Date: Wed, 31 Aug 2016 02:04:35 +0900
Raw View
On 2016/08/30 6:43 +0900, Edward Catmur wrote:
> On Sunday, 28 August 2016 10:58:56 UTC+1, Kazutoshi SATODA wrote:
....
>> I think the situation "pX points to oY" causes some problems:=20
>>
>>   - The semantics of "pX + 1"=20

>>     Proposed resolution (edits by <ins> and <del>):=20
>>       When an expression that has integral type is added to or subtracte=
d=20
>>       from a pointer <ins>to T</ins>, the result has the type of the=20
>>       pointer operand. If the expression P points to element x[i] of an=
=20
>>       array object x <del>with n elements</del><ins>of type T2[n] where=
=20
>>       T2 is similar to T</ins>, ...=20
>>
>>     The resolution makes pX + 1 cause undefined behavior.=20
>=20
> I think that [expr.add]/6 handles this, if a little clumsily:
>=20
>> For addition or subtraction, if the expressions P or Q have type =E2=80=
=9Cpointer=20
>> to cv T=E2=80=9D, where T and the array
>> element type are not similar (4.4), the behavior is undefined.
>=20
> It seems apparent that the "array element type" here is the runtime type =
Y=20
> whereas T is X.

Aha, I missed that paragraph, which was added by CWG #1504.
http://wg21.cmeerw.net/cwg/issue1504.
I'm happy to withdraw this one. Thank you very much.


>>   - The semantics of "pX->...", along with "*pX"=20
....
> Tightening [expr.unary.op]/1 would probably deal with the majority of=20
> cases, but might be viewed as too stringent (it's the old chestnut of=20
> whether &*expr is equivalent to expr...) as with CWG 232.

As for &*expr, I'm wondering that just borrowing the C wording may be
feasible. It says (from WG14 N1570 6.5.3.2 p3):
> The unary & operator yields the address of its operand. If the operand
> has type "type", the result has type "pointer to type". If the operand
> is the result of a unary * operator, neither that operator nor the
> & operator is evaluated and the result is as if both were omitted,
> except that the constraints on the operators still apply and the result
> is not an lvalue.
.... with some additional words to exclude overloaded cases, of course.


--=20
k_satoda

--=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/a8839f89-5b4e-e5ea-273c-3cbde7b0a145%40f2.dion.n=
e.jp.

.