Topic: Pointer arithmetic and inheritance
Author: tl <timlenertz@gmail.com>
Date: Mon, 1 Dec 2014 02:22:32 -0800 (PST)
Raw View
------=_Part_8834_706471887.1417429352369
Content-Type: multipart/alternative;
boundary="----=_Part_8835_235920546.1417429352369"
------=_Part_8835_235920546.1417429352369
Content-Type: text/plain; charset=UTF-8
There is a problem in C++ when using C-style pointer arithmetic along with
subclasses. For instance there are two classes
class point {
public:
float x, y, z;
};
class colored_point : public point {
public:
char r, g, b;
};
Pointers to colored_point can be upcasted to pointers to point. However,
when working with raw buffers (i.e. without using containers or iterators),
pointers are also used to refer to an array of objects of that type.
Pointer arithmetic, i.e. adding or subtracting an integer to a pointer,
then advances the pointer by that number of items.
point* buf = new point [10];
point* buf_end = buf + 10;
for(point* p = buf; p != buf_end; ++p) {
f(*p);
}
However upcasting produces wrong results in that case:
colored_point* original_buf = new colored_point [10];
point* buf = original_buf;
point* buf_end = buf + 10;
for(point* p = buf; p != buf_end; ++p) {
// p will point to space between two colored_point items
f(*p);
}
The code above is valid C++, produces no compilation errors or warnings,
and so hard-to-find bugs can be introduced that way. Maybe it would be
useful to add the possibility to indicate that buf_orig will point to an
array and not to a single item, and then disallow upcasting. Possibly using
an attribute:
colored_point* [[array_pointer]] original_buf = new colored_point [10];
point* buf = original_buf; // ERROR
--
---
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_8835_235920546.1417429352369
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">There is a problem in C++ when using C-style pointer arith=
metic along with subclasses. For instance there are two classes<div><font f=
ace=3D"courier new, monospace"><br></font></div><div><font face=3D"courier =
new, monospace">class point {</font></div><div><font face=3D"courier new, m=
onospace">public:</font></div><div><font face=3D"courier new, monospace">&n=
bsp; float x, y, z;</font></div><div><font face=3D"courier new, mono=
space">};</font></div><div><font face=3D"courier new, monospace">class colo=
red_point : public point {</font></div><div><font face=3D"courier new, mono=
space">public:</font></div><div><font face=3D"courier new, monospace"> =
; char r, g, b;</font></div><div><font face=3D"courier new, monospac=
e">};</font></div><div><font face=3D"courier new, monospace"><br></font></d=
iv><div><font face=3D"arial, sans-serif">Pointers to </font><font face=3D"c=
ourier new, monospace">colored_point</font><font face=3D"arial, sans-serif"=
> can be upcasted to pointers to </font><font face=3D"courier new, monospac=
e">point</font><font face=3D"arial, sans-serif">. However, when working wit=
h raw buffers (i.e. without using containers or iterators), pointers are al=
so used to refer to an array of objects of that type.</font></div><div><fon=
t face=3D"arial, sans-serif">Pointer arithmetic, i.e. adding or subtracting=
an integer to a pointer, then advances the pointer by that number of items=
..</font></div><div><font face=3D"arial, sans-serif"><br></font></div><div><=
font face=3D"courier new, monospace">point* buf =3D new point [10];</font><=
/div><div><font face=3D"courier new, monospace">point* buf_end =3D buf + 10=
;</font></div><div><font face=3D"courier new, monospace">for(point* p =3D b=
uf; p !=3D buf_end; ++p) {</font></div><div><font face=3D"courier new, mono=
space"> f(*p);</font></div><div><font face=3D"courier new, mono=
space">}</font></div><div><font face=3D"courier new, monospace"><br></font>=
</div><div><font face=3D"arial, sans-serif">However upcasting produces wron=
g results in that case:</font></div><div><font face=3D"arial, sans-serif"><=
br></font></div><div><div><font face=3D"courier new, monospace">colored_poi=
nt* original_buf =3D new </font><span style=3D"font-family: 'courier n=
ew', monospace;">colored_point</span><font face=3D"courier new, monospace">=
[10];</font></div><div><font face=3D"courier new, monospace">point* b=
uf =3D </font><span style=3D"font-family: 'courier new', monospace;">o=
riginal_buf;</span></div><div><font face=3D"courier new, monospace">point* =
buf_end =3D buf + 10;</font></div><div><font face=3D"courier new, monospace=
">for(point* p =3D buf; p !=3D buf_end; ++p) {</font></div><div><font face=
=3D"courier new, monospace"> // p will point to space between t=
wo </font><span style=3D"font-family: 'courier new', monospace;">color=
ed_point items</span></div><div><font face=3D"courier new, monospace"> =
; f(*p);</font></div><div><font face=3D"courier new, monospace">}</fo=
nt></div></div><div><font face=3D"courier new, monospace"><br></font></div>=
<div><div><font face=3D"arial, sans-serif">The code above is valid C++, pro=
duces no compilation errors or warnings, and so hard-to-find bugs can be in=
troduced that way. </font><font face=3D"arial, sans-serif">Maybe it wo=
uld be useful to add the possibility to indicate that </font><font face=3D"=
courier new, monospace">buf_orig</font><font face=3D"arial, sans-serif"> wi=
ll point to an array and not to a single item, and then disallow upcasting.=
Possibly using an attribute:</font></div></div><div><font face=3D"arial, s=
ans-serif"><br></font></div><div><div><font face=3D"courier new, monospace"=
>colored_point* [[array_pointer]] original_buf =3D new </font><span st=
yle=3D"font-family: 'courier new', monospace;">colored_point</span><font fa=
ce=3D"courier new, monospace"> [10];</font></div><div><font face=3D"co=
urier new, monospace">point* buf =3D </font><span style=3D"font-family=
: 'courier new', monospace;">original_buf; // ERROR</span></div></div><div>=
<span style=3D"font-family: 'courier new', monospace;"><br></span></div><di=
v><font face=3D"arial, sans-serif"><br></font></div><div><span style=3D"fon=
t-family: arial, sans-serif;"> </span><br></div></div>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
------=_Part_8835_235920546.1417429352369--
------=_Part_8834_706471887.1417429352369--
.
Author: David Krauss <potswa@gmail.com>
Date: Mon, 1 Dec 2014 19:32:32 +0800
Raw View
--Apple-Mail=_54D4D692-7B3C-4844-809B-E014576ABFAC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
On 2014=E2=80=9312=E2=80=9301, at 6:22 PM, tl <timlenertz@gmail.com> wrote:
> Pointers to colored_point can be upcasted to pointers to point. However, =
when working with raw buffers (i.e. without using containers or iterators),=
pointers are also used to refer to an array of objects of that type.
Perhaps one solution is the non-owning smart pointer, as in N3514.
> Maybe it would be useful to add the possibility to indicate that buf_orig=
will point to an array and not to a single item, and then disallow upcasti=
ng. Possibly using an attribute:
>=20
> colored_point* [[array_pointer]] original_buf =3D new colored_point [10];
> point* buf =3D original_buf; // ERROR
Merely having that conversion is innocuous. The question is whether arithme=
tic ever happens to that pointer.
Perhaps a [[single_pointer]] attribute would be less confusing, because tha=
t would express that the given object is incapable of certain operations. P=
erforming arithmetic on a single-item pointer would be an error. The compil=
er could even implicitly apply the attribute opportunistically, given some =
rough rules to statically reason about array and object identity.
--=20
---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.
--Apple-Mail=_54D4D692-7B3C-4844-809B-E014576ABFAC
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset=UTF-8
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dwindows-1252"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-=
mode: space; -webkit-line-break: after-white-space;"><br><div><div>On 2014=
=E2=80=9312=E2=80=9301, at 6:22 PM, tl <<a href=3D"mailto:timlenertz@gma=
il.com">timlenertz@gmail.com</a>> wrote:</div><br class=3D"Apple-interch=
ange-newline"><blockquote type=3D"cite"><div dir=3D"ltr"><div><font face=3D=
"arial, sans-serif">Pointers to </font><font face=3D"courier new, monospace=
">colored_point</font><font face=3D"arial, sans-serif"> can be upcasted to =
pointers to </font><font face=3D"courier new, monospace">point</font><font =
face=3D"arial, sans-serif">. However, when working with raw buffers (i.e. w=
ithout using containers or iterators), pointers are also used to refer to a=
n array of objects of that type.</font></div></div></blockquote><div><br></=
div><div>Perhaps one solution is the non-owning smart pointer, as in <=
a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3514.pdf=
">N3514</a>.</div><br><blockquote type=3D"cite"><div dir=3D"ltr"><div><font=
face=3D"arial, sans-serif">Maybe it would be useful to add the possibility=
to indicate that </font><font face=3D"courier new, monospace">buf_orig</fo=
nt><font face=3D"arial, sans-serif"> will point to an array and not to a si=
ngle item, and then disallow upcasting. Possibly using an attribute:</font>=
</div><div><font face=3D"arial, sans-serif"><br></font></div><div><div><fon=
t face=3D"courier new, monospace">colored_point* [[array_pointer]] original=
_buf =3D new </font><span style=3D"font-family: 'courier new', monospa=
ce;">colored_point</span><font face=3D"courier new, monospace"> [10];<=
/font></div><div><font face=3D"courier new, monospace">point* buf =3D =
</font><span style=3D"font-family: 'courier new', monospace;">original_buf;=
// ERROR</span></div></div></div></blockquote><br></div><div>Merely having=
that conversion is innocuous. The question is whether arithmetic ever happ=
ens to that pointer.</div><div><br></div><div>Perhaps a <font face=3D"Couri=
er">[[single_pointer]]</font> attribute would be less confusing, because th=
at would express that the given object is incapable of certain operations. =
Performing arithmetic on a single-item pointer would be an error. The compi=
ler could even implicitly apply the attribute opportunistically, given some=
rough rules to statically reason about array and object identity.</div></b=
ody></html>
<p></p>
-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />
--Apple-Mail=_54D4D692-7B3C-4844-809B-E014576ABFAC--
.