Topic: Allow char pointers to traverse any part of a dynamic type
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 13 Jun 2017 15:06:48 -0700 (PDT)
Raw View
------=_Part_2615_470638326.1497391608355
Content-Type: multipart/alternative;
boundary="----=_Part_2616_995862832.1497391608355"
------=_Part_2616_995862832.1497391608355
Content-Type: text/plain; charset="UTF-8"
Currently, offsetof has limited use, because the only useful defined way to
use the value returned by offsetof is to access members of a field in a
char array after the class has been copied to it.
My proposal is to allow char pointer arithmetic to traverse any part of the
dynamic type of an object, rather than merely being limited to the
subobject from which the pointer was originally derived. Such an adjusted
char pointer would be allowed to cast back to non-char pointer type, then
accessed, provided that all aliasing rules are followed. That is, if you
cast back to non-char object pointer type and dereference, the type must
more-or-less match the dynamic type of the object or subobject. (I suppose
if you write rather than read, you might end up ending the lifetime of the
object and reusing its storage, which would be legal, but not what you
wanted.)
struct Meow
{
int x;
int y;
};
int BadReadY(Meow *meow)
{
// This function has undefined behavior despite this being true.
static_assert(offsetof(Meow, y) == offsetof(Meow, x) + sizeof(Meow::x));
int *p = &meow->x;
return p[1];
}
int GoodReadY(Meow *meow)
{
static_assert(offsetof(Meow, y) == offsetof(Meow, x) + sizeof(Meow::x));
char *p = reinterpret_cast<char *>(&meow->x);
return *reinterpret_cast<int *>(p + sizeof(Meow::x));
}
The reason for the change is to permit the following kind of code.
Developers do this anyway already, despite having undefined behavior under
the current Standard ([expr.add]/4).
#define CONTAINING_RECORD(address, type, field) \
reinterpret_cast<type *>(reinterpret_cast<char *>(address) -
offsetof(type, field))
Whether this would be legal for non-standard-layout types is a separate
issue; see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0545r0.html
Melissa
--
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/ed72f11f-3897-4bc8-b768-3c4ad3b2e174%40isocpp.org.
------=_Part_2616_995862832.1497391608355
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Currently, offsetof has limited use, because the only usef=
ul defined way to use the value returned by offsetof is to access members o=
f a field in a char array after the class has been copied to it.<br><br>My =
proposal is to allow char pointer arithmetic to traverse any part of the dy=
namic type of an object, rather than merely being limited to the subobject =
from which the pointer was originally derived.=C2=A0 Such an adjusted char =
pointer would be allowed to cast back to non-char pointer type, then access=
ed, provided that all aliasing rules are followed.=C2=A0 That is, if you ca=
st back to non-char object pointer type and dereference, the type must more=
-or-less match the dynamic type of the object or subobject.=C2=A0 (I suppos=
e if you write rather than read, you might end up ending the lifetime of th=
e object and reusing its storage, which would be legal, but not what you wa=
nted.)<br><br><br>struct Meow<br>{<br>=C2=A0=C2=A0=C2=A0 int x;<br>=C2=A0=
=C2=A0=C2=A0 int y;<br>};<br><br>int BadReadY(Meow *meow)<br>{<br>=C2=A0=C2=
=A0=C2=A0 // This function has undefined behavior despite this being true.<=
br>=C2=A0=C2=A0=C2=A0 static_assert(offsetof(Meow, y) =3D=3D offsetof(Meow,=
x) + sizeof(Meow::x));<br><br>=C2=A0=C2=A0=C2=A0 int *p =3D &meow->=
x;<br>=C2=A0=C2=A0=C2=A0 return p[1];<br>}<br><br>int GoodReadY(Meow *meow)=
<br>{<br>=C2=A0=C2=A0=C2=A0 static_assert(offsetof(Meow, y) =3D=3D offsetof=
(Meow, x) + sizeof(Meow::x));<br><br>=C2=A0=C2=A0=C2=A0 char *p =3D reinter=
pret_cast<char *>(&meow->x);<br>=C2=A0=C2=A0=C2=A0 return *rei=
nterpret_cast<int *>(p + sizeof(Meow::x));<br>}<br><br><br>The reason=
for the change is to permit the following kind of code.=C2=A0 Developers d=
o this anyway already, despite having undefined behavior under the current =
Standard ([expr.add]/4).<br><br>#define CONTAINING_RECORD(address, type, fi=
eld) \<br>=C2=A0=C2=A0=C2=A0 reinterpret_cast<type *>(reinterpret_cas=
t<char *>(address) - offsetof(type, field))<br><br><br>Whether this w=
ould be legal for non-standard-layout types is a separate issue; see http:/=
/www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0545r0.html<br><br>Melis=
sa<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/ed72f11f-3897-4bc8-b768-3c4ad3b2e174%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/ed72f11f-3897-4bc8-b768-3c4ad3b2e174=
%40isocpp.org</a>.<br />
------=_Part_2616_995862832.1497391608355--
------=_Part_2615_470638326.1497391608355--
.