Topic: Split trivially-copyable into consistent-layout
Author: Myriachan <myriachan@gmail.com>
Date: Mon, 18 May 2015 13:57:20 -0700 (PDT)
Raw View
------=_Part_1241_1151540110.1431982640538
Content-Type: multipart/alternative;
boundary="----=_Part_1242_812002006.1431982640539"
------=_Part_1242_812002006.1431982640539
Content-Type: text/plain; charset=UTF-8
This is similar to a previous idea I had, but I think that the kinks are
worked out better this time.
I think that we should split trivially-copyable into a new category,
"consistent-layout", separating out the memory layout portions of
trivially-copyable from triviality of copying. I feel that this would make
certain aspects of C++ more orthogonal, as well as put firm grounding in
certain existing practices among programmers. My proposed definitions are
below.
A consistent-layout type is one that occupies contiguous bytes of storage
and whose subobjects are at a consistent constant-expression offset from
the beginning of the object. Access-specifiers do not matter; while it is
true that they may cause ordering differences, they do not affect the fact
that there exists a fixed memory offset to each member. Similarly for
empty base class weirdness.
If a class has no virtual functions and no virtual base classes, it is a
consistent-layout class. Consistent-layout types consist of
consistent-layout classes and fundamental types.
Obviously, offsetof() is redefined to work with consistent-layout classes
instead of standard-layout, with undefined behavior otherwise. Most
compilers are (conceptually) consistent-layout with classes that have
virtual functions, and can implement offsetof() on those, too, but that's
within the purview of undefined behavior.
Trivially-copyable does not need redefinition. Its current definition
implies consistent-layout.
By this definition, trivially-copyable and standard-layout are strict
subsets of consistent-layout, and have an intersection between each other
called plain-old-data.
Consistent-layout and memcpy() / memmove():
Something important is that a consistent-layout class has no internal
compiler bookkeeping relative to a group of unrelated variables of
fundamental type. Constructors and destructors do nothing magical to a
consistent-layout class's members. Calling the constructor isn't critical
to making accessing a class's members defined behavior; initialization is
the critical operation.
Thus, consistent-layout classes are compatible with memcpy() / memmove().
Using them to copy an instance is equivalent to doing a deep memberwise
copy at the fundamental type level. In this sense, all consistent-layout
classes are compatible with memcpy(). If there's undefined behavior, it's
from not using a constructor when you should have, or similar, not from the
language itself. Thus trivially-copyable isn't really special; it's just a
derived consequence. Also, this means that it's safe for a class's copy
constructor to std::memcpy(this, &other, sizeof(*this)).
Just my thoughts on this.
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_1242_812002006.1431982640539
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">This is similar to a previous idea I had, but I think that=
the kinks are worked out better this time.<br><br><br>I think that we shou=
ld split trivially-copyable into a new category, "consistent-layout", separ=
ating out the memory layout portions of trivially-copyable from triviality =
of copying. I feel that this would make certain aspects of C++ more o=
rthogonal, as well as put firm grounding in certain existing practices amon=
g programmers. My proposed definitions are below.<br><br>A consistent=
-layout type is one that occupies contiguous bytes of storage and whose sub=
objects are at a consistent constant-expression offset from the beginning o=
f the object. Access-specifiers do not matter; while it is true that =
they may cause ordering differences, they do not affect the fact that there=
exists a fixed memory offset to each member. Similarly for empty bas=
e class weirdness.<br><br>If a class has no virtual functions and no virtua=
l base classes, it is a consistent-layout class. Consistent-layout ty=
pes consist of consistent-layout classes and fundamental types.<br><br>Obvi=
ously, offsetof() is redefined to work with consistent-layout classes inste=
ad of standard-layout, with undefined behavior otherwise. Most compil=
ers are (conceptually) consistent-layout with classes that have virtual fun=
ctions, and can implement offsetof() on those, too, but that's within the p=
urview of undefined behavior.<br><br>Trivially-copyable does not need redef=
inition. Its current definition implies consistent-layout.<br><br>By =
this definition, trivially-copyable and standard-layout are strict subsets =
of consistent-layout, and have an intersection between each other called pl=
ain-old-data.<br><br><br>Consistent-layout and memcpy() / memmove():<br><br=
>Something important is that a consistent-layout class has no internal comp=
iler bookkeeping relative to a group of unrelated variables of fundamental =
type. Constructors and destructors do nothing magical to a consistent=
-layout class's members. Calling the constructor isn't critical to ma=
king accessing a class's members defined behavior; initialization is the cr=
itical operation.<br><br>Thus, consistent-layout classes are compatible wit=
h memcpy() / memmove(). Using them to copy an instance is equivalent =
to doing a deep memberwise copy at the fundamental type level. In thi=
s sense, all consistent-layout classes are compatible with memcpy(). =
If there's undefined behavior, it's from not using a constructor when you s=
hould have, or similar, not from the language itself. Thus trivially-=
copyable isn't really special; it's just a derived consequence. Also,=
this means that it's safe for a class's copy constructor to std::memcpy(th=
is, &other, sizeof(*this)).<br><br><br>Just my thoughts on this.<br><br=
>Melissa<br></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_1242_812002006.1431982640539--
------=_Part_1241_1151540110.1431982640538--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 18 May 2015 14:35:06 -0700 (PDT)
Raw View
------=_Part_1004_938174327.1431984906403
Content-Type: multipart/alternative;
boundary="----=_Part_1005_1070977615.1431984906403"
------=_Part_1005_1070977615.1431984906403
Content-Type: text/plain; charset=UTF-8
On Monday, May 18, 2015 at 4:57:20 PM UTC-4, Myriachan wrote:
>
> This is similar to a previous idea I had, but I think that the kinks are
> worked out better this time.
>
>
> I think that we should split trivially-copyable into a new category,
> "consistent-layout", separating out the memory layout portions of
> trivially-copyable from triviality of copying.
>
Um, that's already separated. There's the concept of "standard layout
<http://en.cppreference.com/w/cpp/concept/StandardLayoutType>". It means
almost exactly the same thing as you want, and offsetof
<http://en.cppreference.com/w/cpp/types/offsetof> is defined to work with
such types.
The reason that standard layout does not allow for non-empty base classes
or public/private shenanigans is (in part) because `offsetof` works with
them. It's a macro; it's not smart enough to know how to actually do the
computation for things like public/private (because implementations can
reorder them) and base classes can be placed in front of or behind other
classes. Both of these confound a macro like `offsetof`.
--
---
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_1005_1070977615.1431984906403
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, May 18, 2015 at 4:57:20 PM UTC-4, Myria=
chan 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">Th=
is is similar to a previous idea I had, but I think that the kinks are work=
ed out better this time.<br><br><br>I think that we should split trivially-=
copyable into a new category, "consistent-layout", separating out the memor=
y layout portions of trivially-copyable from triviality of copying.</div></=
blockquote><div><br>Um, that's already separated. There's the concept of "<=
a href=3D"http://en.cppreference.com/w/cpp/concept/StandardLayoutType">stan=
dard layout</a>". It means almost exactly the same thing as you want, and <=
a href=3D"http://en.cppreference.com/w/cpp/types/offsetof">offsetof</a> is =
defined to work with such types.<br><br>The reason that standard layout doe=
s not allow for non-empty base classes or public/private shenanigans is (in=
part) because `offsetof` works with them. It's a macro; it's not smart eno=
ugh to know how to actually do the computation for things like public/priva=
te (because implementations can reorder them) and base classes can be place=
d in front of or behind other classes. Both of these confound a macro like =
`offsetof`.<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_1005_1070977615.1431984906403--
------=_Part_1004_938174327.1431984906403--
.
Author: Myriachan <myriachan@gmail.com>
Date: Mon, 18 May 2015 16:26:08 -0700 (PDT)
Raw View
------=_Part_61_1289655868.1431991568787
Content-Type: multipart/alternative;
boundary="----=_Part_62_693724305.1431991568787"
------=_Part_62_693724305.1431991568787
Content-Type: text/plain; charset=UTF-8
On Monday, May 18, 2015 at 2:35:06 PM UTC-7, Nicol Bolas wrote:
>
>
>
> On Monday, May 18, 2015 at 4:57:20 PM UTC-4, Myriachan wrote:
>>
>> This is similar to a previous idea I had, but I think that the kinks are
>> worked out better this time.
>>
>>
>> I think that we should split trivially-copyable into a new category,
>> "consistent-layout", separating out the memory layout portions of
>> trivially-copyable from triviality of copying.
>>
>
> Um, that's already separated. There's the concept of "standard layout
> <http://en.cppreference.com/w/cpp/concept/StandardLayoutType>". It means
> almost exactly the same thing as you want, and offsetof
> <http://en.cppreference.com/w/cpp/types/offsetof> is defined to work with
> such types.
>
> The reason that standard layout does not allow for non-empty base classes
> or public/private shenanigans is (in part) because `offsetof` works with
> them. It's a macro; it's not smart enough to know how to actually do the
> computation for things like public/private (because implementations can
> reorder them) and base classes can be placed in front of or behind other
> classes. Both of these confound a macro like `offsetof`.
>
The current definition of trivially-copyable is such that
trivially-copyable classes *must* be (conceptually) compatible with
offsetof(), because otherwise they don't comply with the Standard in other
ways. With trivially-copyable types, the compiler *already* must be
assigning fixed offsets to each member, and keeping these offsets for the
lifetime of the program. If the compiler did not do this,
Standard-compliant programs would break.
To prove this, let's say that at two different places in a program,
trivially-copyable but non-standard-layout class Meow's member "y" is at
two different offsets "a" and "b". We can construct a contradiction as
below. In the below program, if offset1 ever differs from offset2, because
the compiler has taken liberties with the layout of Meow, then either the
first operation in main() will break, or the second operation in main()
will break. That is, some sort of undefined behavior will occur.
However, this is a contradiction. All the below operations are legal, as
far as I know. You are allowed to alias pointers with unsigned char. You
may also copy trivially-copyable types with memcpy(). memcpy()ing a
trivially-copyable type results in the destination holding the same value.
This does not affect whether the destination has been constructed or
destructed. Thus, object pointers to non-static data members remain valid
across a memcpy() operation--py1 and py2 keep pointing to meow1.y and
meow2.y respectively, even after the data from the allegedly-different
offset y is copied. If this were the case, these pointers could not be
correct, which results in the contradiction.
The end result is that trivially-copyable types *must* be implemented with
each member (and base-class subobject) having a fixed offset for the
ability to be memcpy()'d to make any sense at all. This is the case in the
Standard *right now*, because of what I showed.
The reason I think it'd be worthwhile to make a "consistent-layout"
category is to formally define what makes a class have a memory layout that
matches with the concept of underlying bytes, rather than this halfway
concept we have right now. Standard-layout doesn't cover all the useful
cases.
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <type_traits>
struct Meow
{
int x;
float GetY() const { return y; }
protected:
float y;
friend void Location1();
friend void Location2();
};
static_assert(std::is_trivially_copyable<Meow>::value);
static union
{
unsigned char meowBytes1[sizeof(Meow)];
Meow meow1;
};
std::ptrdiff_t offset1;
unsigned char blob1[sizeof(Meow)];
unsigned char *py1;
static union
{
unsigned char meowBytes2[sizeof(Meow)];
Meow meow2;
};
std::ptrdiff_t offset2;
unsigned char blob2[sizeof(Meow)];
unsigned char *py2;
void Location1()
{
meow1.x = 1;
meow1.y = std::exp(1.0f);
py1 = reinterpret_cast<unsigned char *>(&meow1.y);
offset1 = py1 - meowBytes1;
std::memcpy(blob1, &meow1, sizeof(meow1));
}
void Location2()
{
meow2.x = 2;
meow2.y = 2 * std::asin(1.0f);
py2 = reinterpret_cast<unsigned char *>(&meow2.y);
offset2 = py2 - meowBytes2;
std::memcpy(blob2, &meow2, sizeof(meow2));
}
int main()
{
Location1();
Location2();
float f1 = 123.0f;
std::memcpy(&meow1, blob2, sizeof(meow1));
std::memcpy(py1, &f1, sizeof(f1));
float f2 = 321.0f;
unsigned char temp[sizeof(meow2)];
std::memcpy(temp, blob1, sizeof(temp));
std::memcpy(&temp[offset2], &f2, sizeof(f2));
std::memcpy(&meow2, temp, sizeof(meow2));
std::printf("%f %f\n", meow1.GetY(), meow2.GetY());
std::printf("%td %td\n", offset1, offset2);
return 0;
}
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_62_693724305.1431991568787
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, May 18, 2015 at 2:35:06 PM UTC-7, Nicol Bolas w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><br><br>=
On Monday, May 18, 2015 at 4:57:20 PM UTC-4, Myriachan 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">This is similar to a previous id=
ea I had, but I think that the kinks are worked out better this time.<br><b=
r><br>I think that we should split trivially-copyable into a new category, =
"consistent-layout", separating out the memory layout portions of trivially=
-copyable from triviality of copying.</div></blockquote><div><br>Um, that's=
already separated. There's the concept of "<a href=3D"http://en.cppreferen=
ce.com/w/cpp/concept/StandardLayoutType" target=3D"_blank" rel=3D"nofollow"=
onmousedown=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fen.=
cppreference.com%2Fw%2Fcpp%2Fconcept%2FStandardLayoutType\46sa\75D\46sntz\0=
751\46usg\75AFQjCNHXK2TKPmaoRATO4jXSu8NiyaeUJg';return true;" onclick=3D"th=
is.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2=
Fw%2Fcpp%2Fconcept%2FStandardLayoutType\46sa\75D\46sntz\0751\46usg\75AFQjCN=
HXK2TKPmaoRATO4jXSu8NiyaeUJg';return true;">standard layout</a>". It means =
almost exactly the same thing as you want, and <a href=3D"http://en.cpprefe=
rence.com/w/cpp/types/offsetof" target=3D"_blank" rel=3D"nofollow" onmoused=
own=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fen.cpprefere=
nce.com%2Fw%2Fcpp%2Ftypes%2Foffsetof\46sa\75D\46sntz\0751\46usg\75AFQjCNHUG=
p5mLjZvo0AylXJtmXFOQxoGXw';return true;" onclick=3D"this.href=3D'http://www=
..google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fof=
fsetof\46sa\75D\46sntz\0751\46usg\75AFQjCNHUGp5mLjZvo0AylXJtmXFOQxoGXw';ret=
urn true;">offsetof</a> is defined to work with such types.<br><br>The reas=
on that standard layout does not allow for non-empty base classes or public=
/private shenanigans is (in part) because `offsetof` works with them. It's =
a macro; it's not smart enough to know how to actually do the computation f=
or things like public/private (because implementations can reorder them) an=
d base classes can be placed in front of or behind other classes. Both of t=
hese confound a macro like `offsetof`.<br></div></div></blockquote><div><br=
>The current definition of trivially-copyable is such that trivially-copyab=
le classes <i>must</i> be (conceptually) compatible with offsetof(), becaus=
e otherwise they don't comply with the Standard in other ways. With t=
rivially-copyable types, the compiler <i>already</i> must be assigning fixe=
d offsets to each member, and keeping these offsets for the lifetime of the=
program. If the compiler did not do this, Standard-compliant program=
s would break.<br><br>To prove this, let's say that at two different places=
in a program, trivially-copyable but non-standard-layout class Meow's memb=
er "y" is at two different offsets "a" and "b". We can construct a co=
ntradiction as below. In the below program, if offset1 ever differs f=
rom offset2, because the compiler has taken liberties with the layout of Me=
ow, then either the first operation in main() will break, or the second ope=
ration in main() will break. That is, some sort of undefined behavior=
will occur.<br><br>However, this is a contradiction. All the below o=
perations are legal, as far as I know. You are allowed to alias point=
ers with unsigned char. You may also copy trivially-copyable types wi=
th memcpy(). memcpy()ing a trivially-copyable type results in the des=
tination holding the same value. This does not affect whether the des=
tination has been constructed or destructed. Thus, object pointers to=
non-static data members remain valid across a memcpy() operation--py1 and =
py2 keep pointing to meow1.y and meow2.y respectively, even after the data =
from the allegedly-different offset y is copied. If this were the cas=
e, these pointers could not be correct, which results in the contradiction.=
<br><br>The end result is that trivially-copyable types <i>must</i> be impl=
emented with each member (and base-class subobject) having a fixed offset f=
or the ability to be memcpy()'d to make any sense at all. This is the=
case in the Standard <i>right now</i>, because of what I showed.<br><br>Th=
e reason I think it'd be worthwhile to make a "consistent-layout" category =
is to formally define what makes a class have a memory layout that matches =
with the concept of underlying bytes, rather than this halfway concept we h=
ave right now. Standard-layout doesn't cover all the useful cases.<br=
><br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250=
, 250); border-color: rgb(187, 187, 187); border-style: solid; border-width=
: 1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"su=
bprettyprint"><span style=3D"color: #800;" class=3D"styled-by-prettify">#in=
clude</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #080;" class=3D"styled-by-prettify"><cassert>=
;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #800;" class=3D"styled-by-prettify">#include</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #080;" class=3D"styled-by-prettify"><cmath></span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"><br></span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">#include</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #080;" class=3D"styled-by-prettify"><cstddef></span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color:=
#800;" class=3D"styled-by-prettify">#include</span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #080;" cla=
ss=3D"styled-by-prettify"><cstdio></span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">#include</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #080;" class=3D"style=
d-by-prettify"><cstring></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"><br></span><span style=3D"color: #800;" class=3D"styled=
-by-prettify">#include</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #080;" class=3D"styled-by-prettif=
y"><type_traits></span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">struct</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify">Meo=
w</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> x</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: #008;" class=3D"styled-by-prettify">float</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #606;" =
class=3D"styled-by-prettify">GetY</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">()</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">const</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">return</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> y</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;"=
class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"><br></span><span style=3D"color: #008;" class=3D"styled-by-pret=
tify">protected</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">:</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-pretti=
fy">float</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
y</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: #008;" class=3D"styled-by-prettify">friend</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span =
style=3D"color: #008;" class=3D"styled-by-prettify">void</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Location1</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=
: #008;" class=3D"styled-by-prettify">friend</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Location2</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">();</span><span style=3D"color: #000;" class=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-by-prettify"><br><br></sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">static_assert<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">is_trivially_copyable</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Meow</span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">>::</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify">value</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">static</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">union</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></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: #008;" class=3D"styled-by-prettify">u=
nsigned</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> meowBytes1</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)];</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br> </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> meow1</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ptrdiff_t =
offset1</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: #008;" class=3D"styled-by-prettify">unsigned</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> blob1</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Meow</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)];</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">unsi=
gned</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">py1</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">static</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by=
-prettify">union</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"><br></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: #008;" class=3D"styled-by-prettify">u=
nsigned</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> meowBytes2</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><span sty=
le=3D"color: #008;" class=3D"styled-by-prettify">sizeof</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color=
: #606;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)];</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br> </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"> meow2</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
><br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">ptrdiff_t =
offset2</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: #008;" class=3D"styled-by-prettify">unsigned</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> blob2</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">[</span><span style=3D"color: #008;" c=
lass=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Meow</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)];</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">unsi=
gned</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #008;" class=3D"styled-by-prettify">char</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify">py2</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Location1</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &nbs=
p; meow1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br> meow1</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">y </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">e=
xp</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #066;" class=3D"styled-by-prettify">1.0f</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"><br> py1 </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">reinterpret_cast</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">unsigned</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;"=
class=3D"styled-by-prettify">char</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">*>(&</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">meow1</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">y</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br> =
offset1 </span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> p=
y1 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">-</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> meowBytes1</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"><br> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">memcpy</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify">blob1</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">,</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-prettify">meow1</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> =
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">sizeof</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">meow1</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">));</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">}</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br><br></span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">void</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-p=
rettify">Location2</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br> &nbs=
p; meow2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">.<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">x </span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #066;" class=3D"styled-by-prettify">2</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"><br> meow2</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify">y </span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> </span><span style=3D"color: #066;" class=3D"styled-by-pretti=
fy">2</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">*</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">asin</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">(</span><span style=3D"color: #066;" class=
=3D"styled-by-prettify">1.0f</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br> py2 </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">reinterpret_cast</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify"><</span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">unsigned</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">cha=
r</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">*>(&</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">meow2</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">y</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br><br> offset2 </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> py2 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">-</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> meowBytes2</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"><br> std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">memcpy</span><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">blob2</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">&</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify">meow2</span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008=
;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify">meow2</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"><br></span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> main</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"co=
lor: #660;" class=3D"styled-by-prettify">{</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br> </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Location1</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br> </span><span style=3D"col=
or: #606;" class=3D"styled-by-prettify">Location2</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">();</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"><br><br> </span><span style=3D=
"color: #008;" class=3D"styled-by-prettify">float</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> f1 </span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #066;" class=3D"sty=
led-by-prettify">123.0f</span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br> std</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">memcpy</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(&</span><span style=3D"color: #000;" class=3D"styled-by-prettify">m=
eow1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> blob2</span><s=
pan style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">sizeof</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">meow1</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">));</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"><br> std</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">memcpy</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y">py1</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">&</span><span styl=
e=3D"color: #000;" class=3D"styled-by-prettify">f1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">f1</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=
<br> </span><span style=3D"color: #008;" class=3D"styled-by-pr=
ettify">float</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> f2 </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><s=
pan style=3D"color: #066;" class=3D"styled-by-prettify">321.0f</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: #008;" class=3D"styled-by-prettify">unsigned</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #008;" class=3D"styled-by-prettify">char</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> temp</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">[</span><span style=3D"color: #008;" class=3D"=
styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">meow2</span><span style=3D"color: #660;" class=3D"styled-by-prettify=
">)];</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&=
nbsp; std</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">me=
mcpy</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify">temp</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> blob1</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" clas=
s=3D"styled-by-prettify">sizeof</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">temp</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br> std</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify=
">memcpy</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(&=
amp;</span><span style=3D"color: #000;" class=3D"styled-by-prettify">temp</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">[</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify">offset2</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">],</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">&</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">f2</span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">sizeof</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #000;" class=3D"styled-by-prettify">f2</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">));</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"><br> std</sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify">memcpy</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">(&</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">meow2</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> temp</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-=
prettify">sizeof</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">meo=
w2</span><span style=3D"color: #660;" class=3D"styled-by-prettify">));</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br> =
std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">printf</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><spa=
n style=3D"color: #080;" class=3D"styled-by-prettify">"%f %f\n"</span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> meow1</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">.</span><span style=3D"color: #606;=
" class=3D"styled-by-prettify">GetY</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">(),</span><span style=3D"color: #000;" class=3D"st=
yled-by-prettify"> meow2</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">.</span><span style=3D"color: #606;" class=3D"styled-by-prett=
ify">GetY</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
));</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&nb=
sp; std</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">prin=
tf</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #080;" class=3D"styled-by-prettify">"%td %td\n"</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify"> offset1</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> offset2</span><span style=3D"color:=
#660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"><br><br> </span><span style=3D"co=
lor: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color:=
#000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #066;" c=
lass=3D"styled-by-prettify">0</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">}</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><=
/span></div></code></div><br><br>Melissa<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_62_693724305.1431991568787--
------=_Part_61_1289655868.1431991568787--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 18 May 2015 18:50:24 -0700 (PDT)
Raw View
------=_Part_1220_995110960.1432000224549
Content-Type: multipart/alternative;
boundary="----=_Part_1221_227261884.1432000224549"
------=_Part_1221_227261884.1432000224549
Content-Type: text/plain; charset=UTF-8
On Monday, May 18, 2015 at 7:26:08 PM UTC-4, Myriachan wrote:
>
> On Monday, May 18, 2015 at 2:35:06 PM UTC-7, Nicol Bolas wrote:
>>
>> On Monday, May 18, 2015 at 4:57:20 PM UTC-4, Myriachan wrote:
>>>
>>> This is similar to a previous idea I had, but I think that the kinks are
>>> worked out better this time.
>>>
>>>
>>> I think that we should split trivially-copyable into a new category,
>>> "consistent-layout", separating out the memory layout portions of
>>> trivially-copyable from triviality of copying.
>>>
>>
>> Um, that's already separated. There's the concept of "standard layout
>> <http://en.cppreference.com/w/cpp/concept/StandardLayoutType>". It means
>> almost exactly the same thing as you want, and offsetof
>> <http://en.cppreference.com/w/cpp/types/offsetof> is defined to work
>> with such types.
>>
>> The reason that standard layout does not allow for non-empty base classes
>> or public/private shenanigans is (in part) because `offsetof` works with
>> them. It's a macro; it's not smart enough to know how to actually do the
>> computation for things like public/private (because implementations can
>> reorder them) and base classes can be placed in front of or behind other
>> classes. Both of these confound a macro like `offsetof`.
>>
>
> The current definition of trivially-copyable is such that
> trivially-copyable classes *must* be (conceptually) compatible with
> offsetof(), because otherwise they don't comply with the Standard in other
> ways. With trivially-copyable types, the compiler *already* must be
> assigning fixed offsets to each member, and keeping these offsets for the
> lifetime of the program. If the compiler did not do this,
> Standard-compliant programs would break.
>
> To prove this, let's say that at two different places in a program,
> trivially-copyable but non-standard-layout class Meow's member "y" is at
> two different offsets "a" and "b".
>
Stop. Why would it be at two different offsets? Nobody has claimed that it
*could* be at two different offsets. Indeed, with the exception of virtual
inheritance, there's no circumstance where the offset for a member, given a
pointer to that type, could be different.
So why are you trying to show that a situation is impossible, if nobody's
claiming that it is possible?
`offsetof` is not a compiler intrinsic that is capable of accessing
compiler data; it is nothing more than a C macro (which is why it doesn't
give a static_assert or error if you give it a non-standard layout type).
And while the compiler is capable of compile-time computing the offset for
any non-virtually-inherited member, a simple macro *cannot*.
Remember: `offsetof` is from C. So it has to live by C's rules and behave
as C did. Standard layout types are capable of using it because standard
layout rules effectively define a C-style struct, only in that they allow a
few more C++-isms that don't affect layout.
That's the entire point of the standard layout classification: that the
layout follows the standard C rules. And `offsetof` is based on those rules.
If you want an `offsetof` equivalent that can access trivially copyable
types, then you should ask for that. Though I'm not really sure why you'd
want that; your example code doesn't explain why.
--
---
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_1221_227261884.1432000224549
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, May 18, 2015 at 7:26:08 PM UTC-4, Myriachan wro=
te:<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,=
May 18, 2015 at 2:35:06 PM UTC-7, Nicol Bolas 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">On Monday, May 18, 2015 at 4:57:20 PM UT=
C-4, Myriachan wrote:<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"lt=
r">This is similar to a previous idea I had, but I think that the kinks are=
worked out better this time.<br><br><br>I think that we should split trivi=
ally-copyable into a new category, "consistent-layout", separating out the =
memory layout portions of trivially-copyable from triviality of copying.</d=
iv></blockquote><div><br>Um, that's already separated. There's the concept =
of "<a href=3D"http://en.cppreference.com/w/cpp/concept/StandardLayoutType"=
rel=3D"nofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.=
google.com/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fconcept%2FS=
tandardLayoutType\46sa\75D\46sntz\0751\46usg\75AFQjCNHXK2TKPmaoRATO4jXSu8Ni=
yaeUJg';return true;" onclick=3D"this.href=3D'http://www.google.com/url?q\7=
5http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Fconcept%2FStandardLayoutType\=
46sa\75D\46sntz\0751\46usg\75AFQjCNHXK2TKPmaoRATO4jXSu8NiyaeUJg';return tru=
e;">standard layout</a>". It means almost exactly the same thing as you wan=
t, and <a href=3D"http://en.cppreference.com/w/cpp/types/offsetof" rel=3D"n=
ofollow" target=3D"_blank" onmousedown=3D"this.href=3D'http://www.google.co=
m/url?q\75http%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Foffsetof\46s=
a\75D\46sntz\0751\46usg\75AFQjCNHUGp5mLjZvo0AylXJtmXFOQxoGXw';return true;"=
onclick=3D"this.href=3D'http://www.google.com/url?q\75http%3A%2F%2Fen.cppr=
eference.com%2Fw%2Fcpp%2Ftypes%2Foffsetof\46sa\75D\46sntz\0751\46usg\75AFQj=
CNHUGp5mLjZvo0AylXJtmXFOQxoGXw';return true;">offsetof</a> is defined to wo=
rk with such types.<br><br>The reason that standard layout does not allow f=
or non-empty base classes or public/private shenanigans is (in part) becaus=
e `offsetof` works with them. It's a macro; it's not smart enough to know h=
ow to actually do the computation for things like public/private (because i=
mplementations can reorder them) and base classes can be placed in front of=
or behind other classes. Both of these confound a macro like `offsetof`.<b=
r></div></div></blockquote><div><br>The current definition of trivially-cop=
yable is such that trivially-copyable classes <i>must</i> be (conceptually)=
compatible with offsetof(), because otherwise they don't comply with the S=
tandard in other ways. With trivially-copyable types, the compiler <i=
>already</i> must be assigning fixed offsets to each member, and keeping th=
ese offsets for the lifetime of the program. If the compiler did not =
do this, Standard-compliant programs would break.<br><br>To prove this, let=
's say that at two different places in a program, trivially-copyable but no=
n-standard-layout class Meow's member "y" is at two different offsets "a" a=
nd "b".</div></div></blockquote><div><br>Stop. Why would it be at two diffe=
rent offsets? Nobody has claimed that it <i>could</i> be at two different o=
ffsets. Indeed, with the exception of virtual inheritance, there's no circu=
mstance where the offset for a member, given a pointer to that type, could =
be different.<br><br>So why are you trying to show that a situation is impo=
ssible, if nobody's claiming that it is possible?<br><br>`offsetof` is not =
a compiler intrinsic that is capable of accessing compiler data; it is noth=
ing more than a C macro (which is why it doesn't give a static_assert or er=
ror if you give it a non-standard layout type). And while the compiler is c=
apable of compile-time computing the offset for any non-virtually-inherited=
member, a simple macro <i>cannot</i>.<br><br>Remember: `offsetof` is from =
C. So it has to live by C's rules and behave as C did. Standard layout type=
s are capable of using it because standard layout rules effectively define =
a C-style struct, only in that they allow a few more C++-isms that don't af=
fect layout.<br><br>That's the entire point of the standard layout classifi=
cation: that the layout follows the standard C rules. And `offsetof` is bas=
ed on those rules.<br><br>If you want an `offsetof` equivalent that can acc=
ess trivially copyable types, then you should ask for that. Though I'm not =
really sure why you'd want that; your example code doesn't explain why.<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_1221_227261884.1432000224549--
------=_Part_1220_995110960.1432000224549--
.
Author: David Krauss <potswa@mac.com>
Date: Tue, 19 May 2015 10:22:09 +0800
Raw View
--Apple-Mail=_FB2DBA51-AF68-47CF-A185-964BEE4FE85B
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9319, at 9:50 AM, Nicol Bolas <jmckesson@gmail.c=
om> wrote:
>=20
> `offsetof` is not a compiler intrinsic that is capable of accessing compi=
ler data; it is nothing more than a C macro (which is why it doesn't give a=
static_assert or error if you give it a non-standard layout type).
offsetof is a macro (#ifdef will recognize it) which expands to an intrinsi=
c. The pointer arithmetic implementation is UB and went out of style long a=
go. Also, in both languages it produces a constant expression. In C++ the r=
equisite void* cast is not allowed, even before it could produce UB. In C t=
he pointer arithmetic does not meet the constant expression requirements, b=
ut it leaves constant evaluation open-ended so it=E2=80=99s still implement=
ation-specific.
Clang (by default) warns on all invalid use of offsetof and produces a hard=
error when you apply it to a virtually inherited member. GCC does not impl=
ement the warning, but the error is the same.
--=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=_FB2DBA51-AF68-47CF-A185-964BEE4FE85B
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=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9305=
=E2=80=9319, at 9:50 AM, Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.=
com" class=3D"">jmckesson@gmail.com</a>> wrote:</div><br class=3D"Apple-=
interchange-newline"><div class=3D""><span style=3D"font-family: Helvetica;=
font-size: 12px; font-style: normal; font-variant: normal; font-weight: no=
rmal; letter-spacing: normal; line-height: normal; orphans: auto; text-alig=
n: start; text-indent: 0px; text-transform: none; white-space: normal; wido=
ws: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; d=
isplay: inline !important;" class=3D"">`offsetof` is not a compiler intrins=
ic that is capable of accessing compiler data; it is nothing more than a C =
macro (which is why it doesn't give a static_assert or error if you give it=
a non-standard layout type). </span></div></blockquote><div><br class=3D""=
></div><div><font face=3D"Courier" class=3D"">offsetof</font> is a macro (<=
font face=3D"Courier" class=3D"">#ifdef</font> will recognize it) which exp=
ands to an intrinsic. The pointer arithmetic implementation is UB and went =
out of style long ago. Also, in both languages it produces a constant expre=
ssion. In C++ the requisite <font face=3D"Courier" class=3D"">void*</font> =
cast is not allowed, even before it could produce UB. In C the pointer arit=
hmetic does not meet the constant expression requirements, but it leaves co=
nstant evaluation open-ended so it=E2=80=99s still implementation-specific.=
</div><div><br class=3D""></div><div>Clang (by default) warns on all invali=
d use of <font face=3D"Courier" class=3D"">offsetof</font> and produces a h=
ard error when you apply it to a virtually inherited member. GCC does not i=
mplement the warning, but the error is the same.</div></div></body></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=_FB2DBA51-AF68-47CF-A185-964BEE4FE85B--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 18 May 2015 22:03:08 -0700 (PDT)
Raw View
------=_Part_2121_875258233.1432011788857
Content-Type: multipart/alternative;
boundary="----=_Part_2122_202140081.1432011788857"
------=_Part_2122_202140081.1432011788857
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Monday, May 18, 2015 at 10:22:15 PM UTC-4, David Krauss wrote:
>
> On 2015=E2=80=9305=E2=80=9319, at 9:50 AM, Nicol Bolas <jmck...@gmail.com=
<javascript:>>=20
> wrote:
>
> `offsetof` is not a compiler intrinsic that is capable of accessing=20
> compiler data; it is nothing more than a C macro (which is why it doesn't=
=20
> give a static_assert or error if you give it a non-standard layout type).=
=20
>
>
> offsetof is a macro (#ifdef will recognize it) which expands to an=20
> intrinsic.
>
No, it does not; it expands into something implementation-dependent. This=
=20
could be a compiler intrinsic. Or:
=20
> The pointer arithmetic implementation is UB and went out of style long ag=
o.
>
Undefined behavior can be defined by a particular implementation if they so=
=20
choose. Even if it's just for that particular expression.
So it's perfectly legal for `offsetof` to expand into an expression that is=
=20
undefined behavior by the standard, so long as `offsetof`'s use of that=20
expression yields the correct offset for standard layout types and members.
=20
> Clang (by default) warns on all invalid use of offsetof and produces a=20
> hard error when you apply it to a virtually inherited member. GCC does no=
t=20
> implement the warning, but the error is the same.
>
When I said that it doesn't give an error, I mean that it isn't required by=
=20
the standard to do so. It's considered UB, not a compilation failure.
--=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/.
------=_Part_2122_202140081.1432011788857
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Monday, May 18, 2015 at 10:22:15 PM UTC-4, David Krauss=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap=
:break-word"><div><blockquote type=3D"cite"><div>On 2015=E2=80=9305=E2=80=
=9319, at 9:50 AM, Nicol Bolas <<a href=3D"javascript:" target=3D"_blank=
" gdf-obfuscated-mailto=3D"48nQSQyqDJcJ" rel=3D"nofollow" onmousedown=3D"th=
is.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript:';=
return true;">jmck...@gmail.com</a>> wrote:</div><br><div><span style=3D=
"font-family:Helvetica;font-size:12px;font-style:normal;font-variant:normal=
;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:sta=
rt;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;=
float:none;display:inline!important">`offsetof` is not a compiler intrinsic=
that is capable of accessing compiler data; it is nothing more than a C ma=
cro (which is why it doesn't give a static_assert or error if you give it a=
non-standard layout type). </span></div></blockquote><div><br></div><div><=
font face=3D"Courier">offsetof</font> is a macro (<font face=3D"Courier">#i=
fdef</font> will recognize it) which expands to an intrinsic.</div></div></=
div></blockquote><div><br>No, it does not; it expands into something implem=
entation-dependent. This could be a compiler intrinsic. Or:<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 style=3D"word-wrap:break-=
word"><div><div> The pointer arithmetic implementation is UB and went out o=
f style long ago.</div></div></div></blockquote><div><br>Undefined behavior=
can be defined by a particular implementation if they so choose. Even if i=
t's just for that particular expression.<br><br>So it's perfectly legal for=
`offsetof` to expand into an expression that is undefined behavior by the =
standard, so long as `offsetof`'s use of that expression yields the correct=
offset for standard layout types and members.<br> </div><blockquote c=
lass=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px=
#ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:break-word"><div><d=
iv>Clang (by default) warns on all invalid use of <font face=3D"Courier">of=
fsetof</font> and produces a hard error when you apply it to a virtually in=
herited member. GCC does not implement the warning, but the error is the sa=
me.</div></div></div></blockquote><div><br>When I said that it doesn't give=
an error, I mean that it isn't required by the standard to do so. It's con=
sidered UB, not a compilation failure.<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_2122_202140081.1432011788857--
------=_Part_2121_875258233.1432011788857--
.
Author: Douglas Boffey <douglas.boffey@gmail.com>
Date: Tue, 19 May 2015 01:52:18 -0700 (PDT)
Raw View
------=_Part_2352_1588425673.1432025538822
Content-Type: multipart/alternative;
boundary="----=_Part_2353_1301070254.1432025538822"
------=_Part_2353_1301070254.1432025538822
Content-Type: text/plain; charset=UTF-8
On Monday, 18 May 2015 21:57:20 UTC+1, Myriachan wrote:
>
> This is similar to a previous idea I had, but I think that the kinks are
> worked out better this time.
>
>
> I think that we should split trivially-copyable into a new category,
> "consistent-layout", separating out the memory layout portions of
> trivially-copyable from triviality of copying. I feel that this would make
> certain aspects of C++ more orthogonal, as well as put firm grounding in
> certain existing practices among programmers. My proposed definitions are
> below.
>
> A consistent-layout type is one that occupies contiguous bytes of storage
>
Just a small point, but, unless char and long long have the same alignment,
struct Purr {
char c;
long long ll;
};
does not occupy contiguous bytes of storage ;)
--
---
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_2353_1301070254.1432025538822
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Monday, 18 May 2015 21:57:20 UTC+1, Myriachan =
wrote:<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-widt=
h: 1px; border-left-style: solid;"><div dir=3D"ltr">This is similar to a pr=
evious idea I had, but I think that the kinks are worked out better this ti=
me.<br><br><br>I think that we should split trivially-copyable into a new c=
ategory, "consistent-layout", separating out the memory layout portions of =
trivially-copyable from triviality of copying. I feel that this would=
make certain aspects of C++ more orthogonal, as well as put firm grounding=
in certain existing practices among programmers. My proposed definit=
ions are below.<br></div></blockquote><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;"><div dir=3D"ltr">A consistent-layout type is one that occupies con=
tiguous bytes of storage</div></blockquote><div><br></div><div>Just a small=
point, but, unless char and long long have the same alignment,</div><div><=
br></div><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187=
, 187); border-image: none; -ms-word-wrap: break-word; background-color: rg=
b(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subprettyprint=
"><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 136);">struc=
t</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0);"> =
</span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 0, 102);=
">Purr</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0, 0=
);"> </span><span class=3D"styled-by-prettify" style=3D"color: rgb(102, 102=
, 0);">{</span><span class=3D"styled-by-prettify" style=3D"color: rgb(0, 0,=
0);"><br> </span><span class=3D"styled-by-prettify" style=3D"color: =
rgb(0, 0, 136);">char</span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(0, 0, 0);"> c</span><span class=3D"styled-by-prettify" style=3D"col=
or: rgb(102, 102, 0);">;</span><span class=3D"styled-by-prettify" style=3D"=
color: rgb(0, 0, 0);"><br> </span><span class=3D"styled-by-prettify" =
style=3D"color: rgb(0, 0, 136);">long</span><span class=3D"styled-by-pretti=
fy" style=3D"color: rgb(0, 0, 0);"> </span><span class=3D"styled-by-prettif=
y" style=3D"color: rgb(0, 0, 136);">long</span><span class=3D"styled-by-pre=
ttify" style=3D"color: rgb(0, 0, 0);"> ll</span><span class=3D"styled-by-pr=
ettify" style=3D"color: rgb(102, 102, 0);">;</span><span class=3D"styled-by=
-prettify" style=3D"color: rgb(0, 0, 0);"><br></span><span class=3D"styled-=
by-prettify" style=3D"color: rgb(102, 102, 0);">};</span><span class=3D"sty=
led-by-prettify" style=3D"color: rgb(0, 0, 0);"><br><br></span></div></code=
></div><br><div>does not occupy contiguous bytes of storage ;)</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_2353_1301070254.1432025538822--
------=_Part_2352_1588425673.1432025538822--
.
Author: David Krauss <potswa@mac.com>
Date: Tue, 19 May 2015 21:11:28 +0800
Raw View
--Apple-Mail=_C950FA39-A1BE-48B8-8792-FA9705F80A9A
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9319, at 1:03 PM, Nicol Bolas <jmckesson@gmail.c=
om> wrote:
>=20
> Undefined behavior can be defined by a particular implementation if they =
so choose. Even if it's just for that particular expression.
Not within constant expression evaluation. An expression that invokes UB is=
not a constant expression, even if it=E2=80=99s defined by the implementat=
ion. Before that rule existed, C++98 specifically said =E2=80=9Cpointers=E2=
=80=A6 shall not be used=E2=80=9D in an integral constant expression.
In standard C++, offsetof has always been =E2=80=9Cnearly=E2=80=9D an opera=
tor. It just doesn=E2=80=99t get respect because of its heritage and its ri=
valry with PTMs. (There committee did endorse an evolutionary direction for=
PTMs years ago, to supersede offsetof once and for all, which has been dis=
cussed here more recently.)
--=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=_C950FA39-A1BE-48B8-8792-FA9705F80A9A
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=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D""><br class=3D""><di=
v><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=9305=
=E2=80=9319, at 1:03 PM, Nicol Bolas <<a href=3D"mailto:jmckesson@gmail.=
com" class=3D"">jmckesson@gmail.com</a>> wrote:</div><br class=3D"Apple-=
interchange-newline"><div class=3D""><div dir=3D"ltr" class=3D""><div class=
=3D"">Undefined behavior can be defined by a particular implementation if t=
hey so choose. Even if it's just for that particular expression.<br class=
=3D""></div></div></div></blockquote><div><br class=3D""></div><div>Not wit=
hin constant expression evaluation. An expression that invokes UB is not a =
constant expression, even if it=E2=80=99s defined by the implementation. Be=
fore that rule existed, C++98 specifically said =E2=80=9Cpointers=E2=80=A6 =
shall not be used=E2=80=9D in an integral constant expression.</div><div><b=
r class=3D""></div><div>In standard C++, <font face=3D"Courier" class=3D"">=
offsetof</font> has always been =E2=80=9Cnearly=E2=80=9D an operator. It ju=
st doesn=E2=80=99t get respect because of its heritage and its rivalry with=
PTMs. (There committee <i class=3D"">did</i> endorse an evolutio=
nary direction for PTMs years ago, to supersede <font face=3D"Courier" clas=
s=3D"">offsetof</font> once and for all, which has been discussed here more=
recently.)</div></div></body></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=_C950FA39-A1BE-48B8-8792-FA9705F80A9A--
.
Author: Casey Carter <cartec69@gmail.com>
Date: Tue, 19 May 2015 07:43:19 -0700 (PDT)
Raw View
------=_Part_2404_220348754.1432046599129
Content-Type: multipart/alternative;
boundary="----=_Part_2405_1139701050.1432046599129"
------=_Part_2405_1139701050.1432046599129
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 3:52:18 AM UTC-5, Douglas Boffey wrote:
>
>
> Just a small point, but, unless char and long long have the same alignment,
>
> struct Purr {
> char c;
> long long ll;
> };
>
>
> does not occupy contiguous bytes of storage ;)
>
Every revision of the C++ standard disagrees with you. C++98 1.8/5
(ignoring for the moment that C++98 has no "long long" type):
.... An object of POD type shall occupy contiguous storage.
N4431 (The C++ WP from the 2015-04 pre-meeting mailing) 1.8/5:
.... An object of trivially copyable or standard-layout type shall occupy
contiguous bytes of storage.
The potential existence of padding bytes between the members means that the
members may not be contiguous, but the objects themselves necessarily
occupy contiguous bytes of storage.
--
---
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_2405_1139701050.1432046599129
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 3:52:18 AM UTC-5, Douglas Boff=
ey 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=
><br></div><div>Just a small point, but, unless char and long long have the=
same alignment,</div><div><br></div><div style=3D"border:1px solid rgb(187=
,187,187);background-color:rgb(250,250,250)"><code><div><span style=3D"colo=
r:rgb(0,0,136)">struct</span><span style=3D"color:rgb(0,0,0)"> </span><span=
style=3D"color:rgb(102,0,102)">Purr</span><span style=3D"color:rgb(0,0,0)"=
> </span><span style=3D"color:rgb(102,102,0)">{</span><span style=3D"color:=
rgb(0,0,0)"><br> </span><span style=3D"color:rgb(0,0,136)">char</span=
><span style=3D"color:rgb(0,0,0)"> c</span><span style=3D"color:rgb(102,102=
,0)">;</span><span style=3D"color:rgb(0,0,0)"><br> </span><span style=
=3D"color:rgb(0,0,136)">long</span><span style=3D"color:rgb(0,0,0)"> </span=
><span style=3D"color:rgb(0,0,136)">long</span><span style=3D"color:rgb(0,0=
,0)"> ll</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"=
color:rgb(0,0,0)"><br></span><span style=3D"color:rgb(102,102,0)">};</span>=
<span style=3D"color:rgb(0,0,0)"><br><br></span></div></code></div><br><div=
>does not occupy contiguous bytes of storage ;)</div></div></blockquote><di=
v><br></div><div>Every revision of the C++ standard disagrees with you. C++=
98 1.8/5 (ignoring for the moment that C++98 has no "long long" type):</div=
><div><br></div><div>... An object of POD type shall occupy contiguous stor=
age.</div><div><br></div><div>N4431 (The C++ WP from the 2015-04 pre-meetin=
g mailing) 1.8/5:</div><div><br></div><div>... An object of trivially copya=
ble or standard-layout type shall occupy contiguous bytes of storage.</div>=
<div><br></div><div>The potential existence of padding bytes between the me=
mbers means that the members may not be contiguous, but the objects themsel=
ves necessarily occupy contiguous bytes of storage.</div><div><br></div></d=
iv>
<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_2405_1139701050.1432046599129--
------=_Part_2404_220348754.1432046599129--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 19 May 2015 08:30:31 -0700
Raw View
On Tuesday 19 May 2015 07:43:19 Casey Carter wrote:
> On Tuesday, May 19, 2015 at 3:52:18 AM UTC-5, Douglas Boffey wrote:
> > Just a small point, but, unless char and long long have the same
> > alignment,
> >
> > struct Purr {
> >
> > char c;
> > long long ll;
> >
> > };
> >
> >
> > does not occupy contiguous bytes of storage ;)
>
> Every revision of the C++ standard disagrees with you. C++98 1.8/5
> (ignoring for the moment that C++98 has no "long long" type):
>
> ... An object of POD type shall occupy contiguous storage.
>
> N4431 (The C++ WP from the 2015-04 pre-meeting mailing) 1.8/5:
>
> ... An object of trivially copyable or standard-layout type shall occupy
> contiguous bytes of storage.
>
> The potential existence of padding bytes between the members means that the
> members may not be contiguous, but the objects themselves necessarily
> occupy contiguous bytes of storage.
Or, if you read it in the negative:
there are no bytes between c and ll that aren't part of the object (or, worse,
belong to another object).
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 19 May 2015 12:10:01 -0700 (PDT)
Raw View
------=_Part_2978_2108548215.1432062601062
Content-Type: multipart/alternative;
boundary="----=_Part_2979_594706711.1432062601062"
------=_Part_2979_594706711.1432062601062
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 7:43:19 AM UTC-7, Casey Carter wrote:
>
> On Tuesday, May 19, 2015 at 3:52:18 AM UTC-5, Douglas Boffey wrote:
>>
>>
>> Just a small point, but, unless char and long long have the same
>> alignment,
>>
>> struct Purr {
>> char c;
>> long long ll;
>> };
>>
>>
>> does not occupy contiguous bytes of storage ;)
>>
>
> Every revision of the C++ standard disagrees with you. C++98 1.8/5
> (ignoring for the moment that C++98 has no "long long" type):
>
> ... An object of POD type shall occupy contiguous storage.
>
> N4431 (The C++ WP from the 2015-04 pre-meeting mailing) 1.8/5:
>
> ... An object of trivially copyable or standard-layout type shall occupy
> contiguous bytes of storage.
>
> The potential existence of padding bytes between the members means that
> the members may not be contiguous, but the objects themselves necessarily
> occupy contiguous bytes of storage.
>
>
Additionally (1.7/1):
The fundamental storage unit in the C++ memory model is the *byte*. A byte
> is at least large enough to contain any member of the basic execution
> character set (2.3) and the eight-bit code units of the Unicode UTF-8
> encoding form and is composed of a contiguous sequence of bits, the number
> of which is implementation-defined. ...
>
>
(5.3.3/1):
The sizeof operator yields the number of bytes in the object representation
> of its operand. ... sizeof(char), sizeof(signed char) and sizeof(unsigned
> char) are 1. ...
>
>
So a char or unsigned char array can be used to hold any trivially-copyable
type, which is a key part of 1.8/5 and 3.9/2, and what I was proposing with
"consistent-layout".
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_2979_594706711.1432062601062
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 7:43:19 AM UTC-7, Casey Carter=
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, May 19, 2015 at 3:52:18 AM UTC-5, Douglas Boffey 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"><div><br></div><div>Just a small=
point, but, unless char and long long have the same alignment,</div><div><=
br></div><div style=3D"border:1px solid rgb(187,187,187);background-color:r=
gb(250,250,250)"><code><div><span style=3D"color:rgb(0,0,136)">struct</span=
><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(102,0,10=
2)">Purr</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"colo=
r:rgb(102,102,0)">{</span><span style=3D"color:rgb(0,0,0)"><br> </spa=
n><span style=3D"color:rgb(0,0,136)">char</span><span style=3D"color:rgb(0,=
0,0)"> c</span><span style=3D"color:rgb(102,102,0)">;</span><span style=3D"=
color:rgb(0,0,0)"><br> </span><span style=3D"color:rgb(0,0,136)">long=
</span><span style=3D"color:rgb(0,0,0)"> </span><span style=3D"color:rgb(0,=
0,136)">long</span><span style=3D"color:rgb(0,0,0)"> ll</span><span style=
=3D"color:rgb(102,102,0)">;</span><span style=3D"color:rgb(0,0,0)"><br></sp=
an><span style=3D"color:rgb(102,102,0)">};</span><span style=3D"color:rgb(0=
,0,0)"><br><br></span></div></code></div><br><div>does not occupy contiguou=
s bytes of storage ;)</div></div></blockquote><div><br></div><div>Every rev=
ision of the C++ standard disagrees with you. C++98 1.8/5 (ignoring for the=
moment that C++98 has no "long long" type):</div><div><br></div><div>... A=
n object of POD type shall occupy contiguous storage.</div><div><br></div><=
div>N4431 (The C++ WP from the 2015-04 pre-meeting mailing) 1.8/5:</div><di=
v><br></div><div>... An object of trivially copyable or standard-layout typ=
e shall occupy contiguous bytes of storage.</div><div><br></div><div>The po=
tential existence of padding bytes between the members means that the membe=
rs may not be contiguous, but the objects themselves necessarily occupy con=
tiguous bytes of storage.</div><div><br></div></div></blockquote><div><br>A=
dditionally (1.7/1):<br><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex;=
border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gm=
ail_quote">The fundamental storage unit in the C++ memory model is the <i>b=
yte</i>. A byte is at least large enough to contain any member of the=
basic execution character set (2.3) and the eight-bit code units of the Un=
icode UTF-8 encoding form and is composed of a contiguous sequence of bits,=
the number of which is implementation-defined. ...<br><br></blockquote><br=
>(5.3.3/1):<br><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex; border-l=
eft: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gmail_quote=
">The <span style=3D"font-family: courier new,monospace;">sizeof</span> ope=
rator yields the number of bytes in the object representation of its operan=
d. ... <span style=3D"font-family: courier new,monospace;">sizeof(char)</sp=
an>, <span style=3D"font-family: courier new,monospace;">sizeof(signed char=
)</span> and <span style=3D"font-family: courier new,monospace;">sizeof(uns=
igned char)</span> are <span style=3D"font-family: courier new,monospace;">=
1</span>. ...<br><br></blockquote><br>So a <span style=3D"font-family: cour=
ier new,monospace;">char</span> or <span style=3D"font-family: courier new,=
monospace;">unsigned char</span> array can be used to hold any trivially-co=
pyable type, which is a key part of 1.8/5 and 3.9/2, and what I was proposi=
ng with "consistent-layout".<br><br>Melissa<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_2979_594706711.1432062601062--
------=_Part_2978_2108548215.1432062601062--
.
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 19 May 2015 13:22:18 -0700 (PDT)
Raw View
------=_Part_3235_739142868.1432066938104
Content-Type: multipart/alternative;
boundary="----=_Part_3236_1728768228.1432066938105"
------=_Part_3236_1728768228.1432066938105
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, May 19, 2015 at 6:11:45 AM UTC-7, David Krauss wrote:
>
>
> On 2015=E2=80=9305=E2=80=9319, at 1:03 PM, Nicol Bolas <jmck...@gmail.com=
<javascript:>>=20
> wrote:
>
> Undefined behavior can be defined by a particular implementation if they=
=20
> so choose. Even if it's just for that particular expression.
>
>
> Not within constant expression evaluation. An expression that invokes UB=
=20
> is not a constant expression, even if it=E2=80=99s defined by the impleme=
ntation.=20
> Before that rule existed, C++98 specifically said =E2=80=9Cpointers=E2=80=
=A6 shall not be=20
> used=E2=80=9D in an integral constant expression.
>
> In standard C++, offsetof has always been =E2=80=9Cnearly=E2=80=9D an ope=
rator. It just=20
> doesn=E2=80=99t get respect because of its heritage and its rivalry with =
PTMs.=20
> (There committee *did* endorse an evolutionary direction for PTMs years=
=20
> ago, to supersede offsetof once and for all, which has been discussed=20
> here more recently.)
>
As much as I'd appreciate something like "T void::*", that wouldn't help=20
with interfacing with lower-level code that continues to work with=20
structure offsets. I think the best way is to fix the minor wart with=20
offsetof, then say, "but look, here's a much better C++ way to do it!" with=
=20
"T void::*" or whatever the syntax will be.
My proposal with "consistent-layout" is to ground the current situation in=
=20
reality. Compilers already have to choose a fixed layout for=20
trivially-copyable classes in order to be compatible with memcpy(); this=20
just formalizes it. Additionally, this proposal would answer Core errata=
=20
1701.
Compilers would still be free to put padding in "consistent-layout" classes=
=20
where they need to, reorder fields as desired (subject to the member order=
=20
rule, 9.2/13) and insert hidden fields. They just wouldn't be able to use=
=20
structures that can change at runtime, such that offsetof() would work, as=
=20
would aliasing the class with a char pointer to access individual members,=
=20
if you know the offset. (Undefined behavior would result from accessing=20
the dead space of a non-trivially-copyable class, of course.)
By the way, is the following offsetof() implementation=20
implementation-defined rather than undefined, by 5.2.10/5 ("mappings=20
between pointers and integers are otherwise implementation-defined")? =20
Compilers that allow reinterpret_cast in constexpr (GCC, MSVC, but not=20
clang), which is illegal by the Standard, allow this macro in constant=20
expressions.
#define myria_offsetof(type, ...) \
(static_cast< ::std::size_t>( \
reinterpret_cast<unsigned char *>( \
(&reinterpret_cast<type *>(
static_cast< ::std::uintptr_t>(alignof(type)))->__VA_ARGS__
)) - \
reinterpret_cast<unsigned char *>(
static_cast< ::std::uintptr_t>(alignof(type)))))
Not that I'm recommending such a thing at all...it's rather messy =3D) A=
=20
compiler intrinsic is definitely the way to go. (The use of alignof(type)=
=20
is to avoid undefined behavior with null pointer arithmetic.)
Melissa
--=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/.
------=_Part_3236_1728768228.1432066938105
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 6:11:45 AM UTC-7, David Krauss=
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.=
8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap=
:break-word"><br><div><blockquote type=3D"cite"><div>On 2015=E2=80=9305=E2=
=80=9319, at 1:03 PM, Nicol Bolas <<a href=3D"javascript:" target=3D"_bl=
ank" gdf-obfuscated-mailto=3D"Pncy68udbU4J" rel=3D"nofollow" onmousedown=3D=
"this.href=3D'javascript:';return true;" onclick=3D"this.href=3D'javascript=
:';return true;">jmck...@gmail.com</a>> wrote:</div><br><div><div dir=3D=
"ltr"><div>Undefined behavior can be defined by a particular implementation=
if they so choose. Even if it's just for that particular expression.<br></=
div></div></div></blockquote><div><br></div><div>Not within constant expres=
sion evaluation. An expression that invokes UB is not a constant expression=
, even if it=E2=80=99s defined by the implementation. Before that rule exis=
ted, C++98 specifically said =E2=80=9Cpointers=E2=80=A6 shall not be used=
=E2=80=9D in an integral constant expression.</div><div><br></div><div>In s=
tandard C++, <font face=3D"Courier">offsetof</font> has always been =E2=80=
=9Cnearly=E2=80=9D an operator. It just doesn=E2=80=99t get respect because=
of its heritage and its rivalry with PTMs. (There committee <i>did</i=
> endorse an evolutionary direction for PTMs years ago, to supersede <=
font face=3D"Courier">offsetof</font> once and for all, which has been disc=
ussed here more recently.)</div></div></div></blockquote><div><br>As much a=
s I'd appreciate something like "T void::*", that wouldn't=20
help with interfacing with lower-level code that continues to work with=20
structure offsets. I think the best way is to fix the minor wart with=
offsetof, then say, "but look, here's a much better C++ way to do it!" wit=
h "T void::*" or whatever the syntax will be.<br><br>My proposal with "cons=
istent-layout" is to ground the current situation in reality. Compile=
rs already have to choose a fixed layout for trivially-copyable classes in =
order to be compatible with memcpy(); this just formalizes it. Additi=
onally, this proposal would answer Core errata 1701.<br><br>Compilers would=
still be free to put padding in "consistent-layout" classes where they nee=
d to, reorder fields as desired (subject to the member order rule, 9.2/13) =
and insert hidden fields. They just wouldn't be able to use structure=
s that can change at runtime, such that offsetof() would work, as would ali=
asing the class with a char pointer to access individual members, if you kn=
ow the offset. (Undefined behavior would result from accessing the de=
ad space of a non-trivially-copyable class, of course.)<br><br>By the way, =
is the following <span style=3D"font-family: courier new,monospace;">offset=
of()</span> implementation implementation-defined rather than undefined, by=
5.2.10/5 ("mappings between pointers and integers are otherwise implementa=
tion-defined")? Compilers that allow <span style=3D"font-family: cour=
ier new,monospace;">reinterpret_cast</span> in <span style=3D"font-family: =
courier new,monospace;">constexpr</span> (GCC, MSVC, but not clang), which =
is illegal by the Standard, allow this macro in constant expressions.<br><b=
r><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250, 250);=
border-color: rgb(187, 187, 187); border-style: solid; border-width: 1px; =
word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpretty=
print"><span style=3D"color: #800;" class=3D"styled-by-prettify">#define</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> myria_offset=
of</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">type</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">...)</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">\</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"><br> </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">(</span><span style=3D"color: #008;" class=3D"styled-by-p=
rettify">static_cast</span><span style=3D"color: #660;" class=3D"styled-by-=
prettify"><</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">size_t</span><span style=3D"=
color: #660;" class=3D"styled-by-prettify">>(</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </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"c=
olor: #008;" class=3D"styled-by-prettify">reinterpret_cast</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">unsigned</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;=
" class=3D"styled-by-prettify">char</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">*>(</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">\</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; </span><span style=3D"color: #660;"=
class=3D"styled-by-prettify">(&</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify"><</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify">type </span><span style=3D"color: #660;" class=3D=
"styled-by-prettify">*>(</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br>  =
; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">static_c=
ast</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">uintptr_t</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">>(</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">alignof</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">type</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)))-></span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify">__VA_ARGS__</span><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">))</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">-</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">\</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"><br> </sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_ca=
st</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</sp=
an><span style=3D"color: #008;" class=3D"styled-by-prettify">unsigned</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">char</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </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: #008;" class=3D"styled-by-prettify">static_c=
ast</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">uintptr_t</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">>(</span><span style=3D"color: #008;" cla=
ss=3D"styled-by-prettify">alignof</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify">type</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">)))))</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br></span></div></code></div><br>Not that I'm recommending such a thin=
g at all...it's rather messy =3D) A compiler intrinsic is definitely =
the way to go. (The use of alignof(type) is to avoid undefined behavi=
or with null pointer arithmetic.)<br><br>Melissa<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_3236_1728768228.1432066938105--
------=_Part_3235_739142868.1432066938104--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 May 2015 13:33:01 -0700 (PDT)
Raw View
------=_Part_633_585957667.1432067581222
Content-Type: multipart/alternative;
boundary="----=_Part_634_1977987774.1432067581222"
------=_Part_634_1977987774.1432067581222
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
On Tuesday, May 19, 2015 at 4:22:18 PM UTC-4, Myriachan wrote:
>
> On Tuesday, May 19, 2015 at 6:11:45 AM UTC-7, David Krauss wrote:
>>
>>
>> On 2015=E2=80=9305=E2=80=9319, at 1:03 PM, Nicol Bolas <jmck...@gmail.co=
m> wrote:
>>
>> Undefined behavior can be defined by a particular implementation if they=
=20
>> so choose. Even if it's just for that particular expression.
>>
>>
>> Not within constant expression evaluation. An expression that invokes UB=
=20
>> is not a constant expression, even if it=E2=80=99s defined by the implem=
entation.=20
>> Before that rule existed, C++98 specifically said =E2=80=9Cpointers=E2=
=80=A6 shall not be=20
>> used=E2=80=9D in an integral constant expression.
>>
>> In standard C++, offsetof has always been =E2=80=9Cnearly=E2=80=9D an op=
erator. It just=20
>> doesn=E2=80=99t get respect because of its heritage and its rivalry with=
PTMs.=20
>> (There committee *did* endorse an evolutionary direction for PTMs years=
=20
>> ago, to supersede offsetof once and for all, which has been discussed=20
>> here more recently.)
>>
>
> As much as I'd appreciate something like "T void::*", that wouldn't help=
=20
> with interfacing with lower-level code that continues to work with=20
> structure offsets. I think the best way is to fix the minor wart with=20
> offsetof, then say, "but look, here's a much better C++ way to do it!" wi=
th=20
> "T void::*" or whatever the syntax will be.
>
> My proposal with "consistent-layout" is to ground the current situation i=
n=20
> reality. Compilers already have to choose a fixed layout for=20
> trivially-copyable classes in order to be compatible with memcpy(); this=
=20
> just formalizes it. Additionally, this proposal would answer Core errata=
=20
> 1701.
>
I don't understand this. With the exception of members of virtual base=20
classes, compilers have to choose a fixed layout for *all classes*. But=20
having a fixed layout and being copyable isn't the same thing. That's why=
=20
it's "trivially copyable" that decides whether memcpy works, not "standard=
=20
layout".
If you want to expand `offsetof` to make it work for trivially copyable=20
classes (all standard layout types are also trivially copyable, IIRC),=20
well, OK, but it's kind of a C thing. I'd much rather see a proper C++=20
intrinsic (vis-a-vis reflection) than to reuse a macro.
But if you want a new value category that is "ground[ed] the current=20
situation in reality"... then really, it should work for any type+member,=
=20
where the referenced member is not a member of a virtual base class. So it=
=20
wouldn't even be a type category, as it depends on the relationship between=
=20
the type and the specified member.
--=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/.
------=_Part_634_1977987774.1432067581222
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 19, 2015 at 4:22:18 PM UTC-4, Myri=
achan 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">O=
n Tuesday, May 19, 2015 at 6:11:45 AM UTC-7, David Krauss wrote:<blockquote=
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px =
#ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word"><br><div><=
blockquote type=3D"cite"><div>On 2015=E2=80=9305=E2=80=9319, at 1:03 PM, Ni=
col Bolas <<a rel=3D"nofollow">jmck...@gmail.com</a>> wrote:</div><br=
><div><div dir=3D"ltr"><div>Undefined behavior can be defined by a particul=
ar implementation if they so choose. Even if it's just for that particular =
expression.<br></div></div></div></blockquote><div><br></div><div>Not withi=
n constant expression evaluation. An expression that invokes UB is not a co=
nstant expression, even if it=E2=80=99s defined by the implementation. Befo=
re that rule existed, C++98 specifically said =E2=80=9Cpointers=E2=80=A6 sh=
all not be used=E2=80=9D in an integral constant expression.</div><div><br>=
</div><div>In standard C++, <font face=3D"Courier">offsetof</font> has alwa=
ys been =E2=80=9Cnearly=E2=80=9D an operator. It just doesn=E2=80=99t get r=
espect because of its heritage and its rivalry with PTMs. (There committee&=
nbsp;<i>did</i> endorse an evolutionary direction for PTMs years ago, =
to supersede <font face=3D"Courier">offsetof</font> once and for all, which=
has been discussed here more recently.)</div></div></div></blockquote><div=
><br>As much as I'd appreciate something like "T void::*", that wouldn't=20
help with interfacing with lower-level code that continues to work with=20
structure offsets. I think the best way is to fix the minor wart with=
offsetof, then say, "but look, here's a much better C++ way to do it!" wit=
h "T void::*" or whatever the syntax will be.<br><br>My proposal with "cons=
istent-layout" is to ground the current situation in reality. Compile=
rs already have to choose a fixed layout for trivially-copyable classes in =
order to be compatible with memcpy(); this just formalizes it. Additi=
onally, this proposal would answer Core errata 1701.<br></div></div></block=
quote><div><br>I don't understand this. With the exception of members of vi=
rtual base classes, compilers have to choose a fixed layout for <i>all clas=
ses</i>. But having a fixed layout and being copyable isn't the same thing.=
That's why it's "trivially copyable" that decides whether memcpy works, no=
t "standard layout".<br><br>If you want to expand `offsetof` to make it wor=
k for trivially copyable classes (all standard layout types are also trivia=
lly copyable, IIRC), well, OK, but it's kind of a C thing. I'd much rather =
see a proper C++ intrinsic (vis-a-vis reflection) than to reuse a macro.<br=
><br>But if you want a new value category that is "ground[ed] the current s=
ituation in reality"... then really, it should work for any type+member, wh=
ere the referenced member is not a member of a virtual base class. So it wo=
uldn't even be a type category, as it depends on the relationship between t=
he type and the specified member.<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_634_1977987774.1432067581222--
------=_Part_633_585957667.1432067581222--
.
Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Wed, 20 May 2015 00:04:29 +0300
Raw View
On 19 May 2015 at 23:33, Nicol Bolas <jmckesson@gmail.com> wrote:
> If you want to expand `offsetof` to make it work for trivially copyable
> classes (all standard layout types are also trivially copyable, IIRC), well,
That's not correct. A standard-layout type can easily be non-trivially copyable.
[class]/10 has an example.
--
---
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/.
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 May 2015 14:15:47 -0700 (PDT)
Raw View
------=_Part_915_2008916989.1432070147414
Content-Type: multipart/alternative;
boundary="----=_Part_916_636276702.1432070147414"
------=_Part_916_636276702.1432070147414
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 5:04:31 PM UTC-4, Ville Voutilainen wrote:
>
> On 19 May 2015 at 23:33, Nicol Bolas <jmck...@gmail.com <javascript:>>
> wrote:
> > If you want to expand `offsetof` to make it work for trivially copyable
> > classes (all standard layout types are also trivially copyable, IIRC),
> well,
>
> That's not correct. A standard-layout type can easily be non-trivially
> copyable.
> [class]/10 has an example.
>
OK, good point.
That being said, you could still expand the definition of `offsetof` (or
better yet, make a new thing that is a real intrinsic) which can get a
compile-time offset from any type+member, as long as it doesn't have to go
through a virtual base class. That's a superset of both standard layout and
trivially copyable.
--
---
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_916_636276702.1432070147414
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 5:04:31 PM UTC-4, Ville Voutil=
ainen wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-lef=
t: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 19 May 2015 at =
23:33, Nicol Bolas <<a href=3D"javascript:" target=3D"_blank" gdf-obfusc=
ated-mailto=3D"zKA88rRpUycJ" rel=3D"nofollow" onmousedown=3D"this.href=3D'j=
avascript:';return true;" onclick=3D"this.href=3D'javascript:';return true;=
">jmck...@gmail.com</a>> wrote:
<br>> If you want to expand `offsetof` to make it work for trivially cop=
yable
<br>> classes (all standard layout types are also trivially copyable, II=
RC), well,
<br>
<br>That's not correct. A standard-layout type can easily be non-trivially =
copyable.
<br>[class]/10 has an example.<br></blockquote><div><br>OK, good point.<br>=
<br>That being said, you could still expand the definition of `offsetof` (o=
r better yet, make a new thing that is a real intrinsic) which can get a co=
mpile-time offset from any type+member, as long as it doesn't have to go th=
rough a virtual base class. That's a superset of both standard layout and t=
rivially copyable.<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_916_636276702.1432070147414--
------=_Part_915_2008916989.1432070147414--
.
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 19 May 2015 17:12:04 -0700 (PDT)
Raw View
------=_Part_3384_113315845.1432080724628
Content-Type: multipart/alternative;
boundary="----=_Part_3385_1828895673.1432080724628"
------=_Part_3385_1828895673.1432080724628
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 2:15:47 PM UTC-7, Nicol Bolas wrote:
>
> On Tuesday, May 19, 2015 at 5:04:31 PM UTC-4, Ville Voutilainen wrote:
>>
>> That's not correct. A standard-layout type can easily be non-trivially
>> copyable.
>> [class]/10 has an example.
>>
>
> OK, good point.
>
> That being said, you could still expand the definition of `offsetof` (or
> better yet, make a new thing that is a real intrinsic) which can get a
> compile-time offset from any type+member, as long as it doesn't have to go
> through a virtual base class. That's a superset of both standard layout and
> trivially copyable.
>
The current rule only requires that trivially-copyable and standard-layout
types occupy contiguous memory (1.8/5):
.... An object of trivially copyable or standard-layout type (3.9) shall
> occupy contiguous bytes of storage.
>
In other words, types with nontrivial copy constructors or destructors, or
classes with virtual functions, etc. yet don't have virtual base classes
can have strange layouts under current rules. They can be implemented with
internal hidden pointers similar to the way some compilers implement
virtual base classes if the compiler so chooses. Such an implementation is
silly, particularly if virtual functions are not involved, but doesn't
appear to be barred by anything in the Standard.
My "consistent-layout" proposal would arrange things as follows.
"Consistent-layout" is a class with no virtual functions and no virtual
base classes; thus, standard-layout and trivially-copyable are proper
subsets.
A: All data members go in order. (If not A, member order is still somewhat
restricted by 9.2/13.)
B: Two classes with the same initial sequence of members of similar types
are layout-compatible in those members.
C: A class instance may be copied to another with memcpy().
D: A class instance may safely be copied to a char array and back.
E: offsetof is permitted.
F: A data member of a class instance may be accessed by aliasing the class
with a char pointer and adding the member's offset. (*)
Plain old data: ABCDEF
Standard-layout: ABEF
Trivially-copyable: CDEF
Consistent-layout: EF
Polymorphic: conditionally supported: EF, otherwise naught
With virtual bases: naught
(*) Base class subobjects may not be accessed in this manner, but their
members, if any, may be. Which, by the way, is something that offsetof can
do and member pointers still cannot... =/
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3385_1828895673.1432080724628
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 2:15:47 PM UTC-7, Nicol Bolas =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On Tues=
day, May 19, 2015 at 5:04:31 PM UTC-4, Ville Voutilainen wrote:<blockquote =
class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #=
ccc solid;padding-left:1ex">That's not correct. A standard-layout type can =
easily be non-trivially copyable.
<br>[class]/10 has an example.<br></blockquote><div><br>OK, good point.<br>=
<br>That being said, you could still expand the definition of `offsetof` (o=
r better yet, make a new thing that is a real intrinsic) which can get a co=
mpile-time offset from any type+member, as long as it doesn't have to go th=
rough a virtual base class. That's a superset of both standard layout and t=
rivially copyable.<br></div></div></blockquote><div><br>The current rule on=
ly requires that trivially-copyable and standard-layout types occupy contig=
uous memory (1.8/5):<br><br><blockquote style=3D"margin: 0px 0px 0px 0.8ex;=
border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;" class=3D"gm=
ail_quote">... An object of trivially copyable or standard-layout type (3.9=
) shall occupy contiguous bytes of storage.<br></blockquote><br>In other wo=
rds, types with nontrivial copy constructors or destructors, or classes wit=
h virtual functions, etc. yet don't have virtual base classes can have stra=
nge layouts under current rules. They can be implemented with interna=
l hidden pointers similar to the way some compilers implement virtual base =
classes if the compiler so chooses. Such an implementation is silly, =
particularly if virtual functions are not involved, but doesn't appear to b=
e barred by anything in the Standard.<br><br>My "consistent-layout" proposa=
l would arrange things as follows. "Consistent-layout" is a class wit=
h no virtual functions and no virtual base classes; thus, standard-layout a=
nd trivially-copyable are proper subsets.<br><br>A: All data members go in =
order. (If not A, member order is still somewhat restricted by 9.2/13=
..)<br>B: Two classes with the same initial sequence of members of similar t=
ypes are layout-compatible in those members.<br>C: A class instance may be =
copied to another with memcpy().<br>D: A class instance may safely be copie=
d to a char array and back.<br>E: offsetof is permitted.<br>F: A data membe=
r of a class instance may be accessed by aliasing the class with a char poi=
nter and adding the member's offset. (*)<br><br>Plain old data: ABCDEF<br>S=
tandard-layout: ABEF<br>Trivially-copyable: CDEF<br>Consistent-layout: EF<b=
r>Polymorphic: conditionally supported: EF, otherwise naught<br>With virtua=
l bases: naught<br><br>(*) Base class subobjects may not be accessed in thi=
s manner, but their members, if any, may be. Which, by the way, is so=
mething that offsetof can do and member pointers still cannot... =3D/<br><b=
r>Melissa<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_3385_1828895673.1432080724628--
------=_Part_3384_113315845.1432080724628--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 May 2015 18:10:22 -0700 (PDT)
Raw View
------=_Part_3228_2004246946.1432084222955
Content-Type: multipart/alternative;
boundary="----=_Part_3229_2097418227.1432084222955"
------=_Part_3229_2097418227.1432084222955
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 8:12:04 PM UTC-4, Myriachan wrote:
>
> On Tuesday, May 19, 2015 at 2:15:47 PM UTC-7, Nicol Bolas wrote:
>>
>> On Tuesday, May 19, 2015 at 5:04:31 PM UTC-4, Ville Voutilainen wrote:
>>>
>>> That's not correct. A standard-layout type can easily be non-trivially
>>> copyable.
>>> [class]/10 has an example.
>>>
>>
>> OK, good point.
>>
>> That being said, you could still expand the definition of `offsetof` (or
>> better yet, make a new thing that is a real intrinsic) which can get a
>> compile-time offset from any type+member, as long as it doesn't have to go
>> through a virtual base class. That's a superset of both standard layout and
>> trivially copyable.
>>
>
> The current rule only requires that trivially-copyable and standard-layout
> types occupy contiguous memory (1.8/5):
>
> ... An object of trivially copyable or standard-layout type (3.9) shall
>> occupy contiguous bytes of storage.
>>
>
> In other words, types with nontrivial copy constructors or destructors, or
> classes with virtual functions, etc. yet don't have virtual base classes
> can have strange layouts under current rules. They can be implemented with
> internal hidden pointers similar to the way some compilers implement
> virtual base classes if the compiler so chooses. Such an implementation is
> silly, particularly if virtual functions are not involved, but doesn't
> appear to be barred by anything in the Standard.
>
True. But the reason the C++98/03 notion of POD said something similar. Yet
in C++11, they changed the rules, so that more types could be considered to
have "contiguous memory". The reason they changed those rules was because
compilers already handled them.
Do you know of compilers that implement classes, such that the offset from
a pointer to type T to any non-virtual base member is *not* a compile-time
constant? If all compilers implement classes such that the non-virtual-base
members of any particular class have a consistent byte offset, then you
don't need this classification at all. The only thing you need is a new
version of `offsetof` that can take any type/member pair, so long as the
member is in a virtual base of the type.
Is your choice of excluding all polymorphic types based on actual knowledge
of how compilers work? Or is it based on something else?
I say this because, as previously stated, I've worked on a serialization
system that had to write data via code from one compiler, and read it with
code from another one. Or rather, code from another *three* compilers. That
compiled code for three very different CPUs, running on three very
different systems.
And *we* managed to get virtuals working (it required lots and lots of UB,
but we did it). Now, we didn't try virtual inheritance. But we had regular
inheritance going, along with virtual functions. At no time were we stopped
by a compiler that didn't have static offsets for members of polymorphic
types.
Note that these compilers did have lots of differences. Of particular note
were variances between where the base class goes relative to the derived.
On one platform, it was after, while on the others, it was before.
And yet, at no time were there non-static offsets for members of
polymorphic types.
So do you have actual experience with actual compilers that show that
compilers will have variances regarding polymorphic types? If you haven't
done the research, then my first suggestion would be to actually do the
research and find out where the *real* intersection of your features E&F
are. Not merely to think you know it, but to actually know where that
intersection is in actual, live compilers.
Also, from the examples you've given, I smell some kind of horrible
serialization system behind this request, one that uses byte offsets and
such to serialize members and so forth, rather than being hard-coded to the
member names. My concern there is that reflection will basically do
everything you need, and do it better, in a way that won't require this
kind of low-level fiddling.
This would also explain why you're willing to sacrifice polymorphic types
entirely. Reconstructing such data from a serialized object would be very
difficult. So your serialization system would consider it out of scope.
Thus, it's not part of your proposal.
If so, maybe it would be better to wait for the right solution (reflection)
than to modify the standard in such a way. I would hate for the committee
to standardize something, only for another feature to come along and make
it a moot point (re: std::bind. Good idea at the time, dumb idea with
lambdas around).
--
---
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_3229_2097418227.1432084222955
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 8:12:04 PM UTC-4, Myriachan 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 Tuesda=
y, May 19, 2015 at 2:15:47 PM UTC-7, Nicol Bolas wrote:<blockquote class=3D=
"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc soli=
d;padding-left:1ex"><div dir=3D"ltr">On Tuesday, May 19, 2015 at 5:04:31 PM=
UTC-4, Ville Voutilainen wrote:<blockquote class=3D"gmail_quote" style=3D"=
margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding-left:1ex">Tha=
t's not correct. A standard-layout type can easily be non-trivially copyabl=
e.
<br>[class]/10 has an example.<br></blockquote><div><br>OK, good point.<br>=
<br>That being said, you could still expand the definition of `offsetof` (o=
r better yet, make a new thing that is a real intrinsic) which can get a co=
mpile-time offset from any type+member, as long as it doesn't have to go th=
rough a virtual base class. That's a superset of both standard layout and t=
rivially copyable.<br></div></div></blockquote><div><br>The current rule on=
ly requires that trivially-copyable and standard-layout types occupy contig=
uous memory (1.8/5):<br><br><blockquote style=3D"margin:0px 0px 0px 0.8ex;b=
order-left:1px solid rgb(204,204,204);padding-left:1ex" class=3D"gmail_quot=
e">... An object of trivially copyable or standard-layout type (3.9) shall =
occupy contiguous bytes of storage.<br></blockquote><br>In other words, typ=
es with nontrivial copy constructors or destructors, or classes with virtua=
l functions, etc. yet don't have virtual base classes can have strange layo=
uts under current rules. They can be implemented with internal hidden=
pointers similar to the way some compilers implement virtual base classes =
if the compiler so chooses. Such an implementation is silly, particul=
arly if virtual functions are not involved, but doesn't appear to be barred=
by anything in the Standard.<br></div></div></blockquote><div><br>True. Bu=
t the reason the C++98/03 notion of POD said something similar. Yet in C++1=
1, they changed the rules, so that more types could be considered to have "=
contiguous memory". The reason they changed those rules was because compile=
rs already handled them.<br><br>Do you know of compilers that implement cla=
sses, such that the offset from a pointer to type T to any non-virtual base=
member is <i>not</i> a compile-time constant? If all compilers implement c=
lasses such that the non-virtual-base members of any particular class have =
a consistent byte offset, then you don't need this classification at all. T=
he only thing you need is a new version of `offsetof` that can take any typ=
e/member pair, so long as the member is in a virtual base of the type.<br><=
br>Is your choice of excluding all polymorphic types based on actual knowle=
dge of how compilers work? Or is it based on something else?<br><br>I say t=
his because, as previously stated, I've worked on a serialization system th=
at had to write data via code from one compiler, and read it with code from=
another one. Or rather, code from another <i>three</i> compilers. That com=
piled code for three very different CPUs, running on three very different s=
ystems.<br><br>And <i>we</i> managed to get virtuals working (it required l=
ots and lots of UB, but we did it). Now, we didn't try virtual inheritance.=
But we had regular inheritance going, along with virtual functions. At no =
time were we stopped by a compiler that didn't have static offsets for memb=
ers of polymorphic types.<br><br>Note that these compilers did have lots of=
differences. Of particular note were variances between where the base clas=
s goes relative to the derived. On one platform, it was after, while on the=
others, it was before.<br><br>And yet, at no time were there non-static of=
fsets for members of polymorphic types.<br><br>So do you have actual experi=
ence with actual compilers that show that compilers will have variances reg=
arding polymorphic types? If you haven't done the research, then my first s=
uggestion would be to actually do the research and find out where the <i>re=
al</i> intersection of your features E&F are. Not merely to think you k=
now it, but to actually know where that intersection is in actual, live com=
pilers.<br><br>Also, from the examples you've given, I smell some kind of h=
orrible serialization system behind this request, one that uses byte offset=
s and such to serialize members and so forth, rather than being hard-coded =
to the member names. My concern there is that reflection will basically do =
everything you need, and do it better, in a way that won't require this kin=
d of low-level fiddling.<br><br>This would also explain why you're willing =
to sacrifice polymorphic types entirely. Reconstructing such data from a se=
rialized object would be very difficult. So your serialization system would=
consider it out of scope. Thus, it's not part of your proposal.<br><br>If =
so, maybe it would be better to wait for the right solution (reflection) th=
an to modify the standard in such a way. I would hate for the committee to =
standardize something, only for another feature to come along and make it a=
moot point (re: std::bind. Good idea at the time, dumb idea with lambdas a=
round).<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_3229_2097418227.1432084222955--
------=_Part_3228_2004246946.1432084222955--
.
Author: Zhihao Yuan <zy@miator.net>
Date: Tue, 19 May 2015 21:17:40 -0400
Raw View
On Tue, May 19, 2015 at 8:12 PM, Myriachan <myriachan@gmail.com> wrote:
>
> My "consistent-layout" proposal would arrange things as follows.
> "Consistent-layout" is a class with no virtual functions and no virtual base
> classes; thus, standard-layout and trivially-copyable are proper subsets.
>
> A: All data members go in order. (If not A, member order is still somewhat
> restricted by 9.2/13.)
> B: Two classes with the same initial sequence of members of similar types
> are layout-compatible in those members.
> C: A class instance may be copied to another with memcpy().
> D: A class instance may safely be copied to a char array and back.
> E: offsetof is permitted.
> F: A data member of a class instance may be accessed by aliasing the class
> with a char pointer and adding the member's offset. (*)
>
> Plain old data: ABCDEF
> Standard-layout: ABEF
> Trivially-copyable: CDEF
> Consistent-layout: EF
> Polymorphic: conditionally supported: EF, otherwise naught
> With virtual bases: naught
Although I'm not a core guy, the explanation is very clear to me.
Even we don't like offsetof right now, such a proposal may
benefit future language extensions like reflection.
>
> (*) Base class subobjects may not be accessed in this manner, but their
> members, if any, may be. Which, by the way, is something that offsetof can
> do and member pointers still cannot... =/
>
> Melissa
--
Zhihao Yuan, ID lichray
The best way to predict the future is to invent it.
___________________________________________________
4BSD -- http://bit.ly/blog4bsd
--
---
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/.
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 19 May 2015 18:28:48 -0700
Raw View
On Tuesday 19 May 2015 17:12:04 Myriachan wrote:
> A: All data members go in order. (If not A, member order is still somewhat
> restricted by 9.2/13.)
> B: Two classes with the same initial sequence of members of similar types
> are layout-compatible in those members.
> C: A class instance may be copied to another with memcpy().
> D: A class instance may safely be copied to a char array and back.
> E: offsetof is permitted.
> F: A data member of a class instance may be accessed by aliasing the class
> with a char pointer and adding the member's offset.
>
> Plain old data: ABCDEF
> Standard-layout: ABEF
> Trivially-copyable: CDEF
> Consistent-layout: EF
> Polymorphic: conditionally supported: EF, otherwise naught
> With virtual bases: naught
I don't think we need to create a new type for this. Simply change 18.2
[support.types] p4:
- If type is not a standard-layout class (Clause 9), the results are
undefined.
+ If type is not a standard-layout or trivially copyable class (Clause 9), the
results are undefined.
Or refer to the contiguous storage definition from 1.8/5 that you quoted.
I personally don't think we should overcomplicate this because offsetof is
supposed to be low-level C code. C code shouldn't be dealing with more complex
C++ types -- for that, we can have a C++ solution, including the subtraction
operator with pointer-to-members.
struct S
{
int i;
};
void f()
{
S s{0};
auto pm1 = &S::i;
int *p1 = pm1 - &s;
*p1 = 1;
assert(s.i == 1);
}
This bypasses the need for F.
I don't like the void pointer-to-member suggestion because it erases the type
like plain void* does. And I can't think of other use-cases where I'd like to
store type-erased offsets, not real pointers -- though it might be interesting
to have
template <type Member, typename Outer> ptrdiff_t
make_offset(Outer *object, Member Outer:: *pointer_to_member);
template <type Member, typename Outer> Member Outer::*
make_pointer_to_member(Outer *object, ptrdiff_t offset);
On quite a few ABIs, the pointer to member *is* an offset anyway and those two
functions would ignore the first argument and return a reinterpreted second
argument.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.
Author: David Krauss <potswa@gmail.com>
Date: Wed, 20 May 2015 09:53:45 +0800
Raw View
--Apple-Mail=_A2AC0D46-F1AC-4FE5-8E12-1CD8EA3FC4B4
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
> On 2015=E2=80=9305=E2=80=9320, at 4:22 AM, Myriachan <myriachan@gmail.com=
<mailto:myriachan@gmail.com>> wrote:
>=20
> As much as I'd appreciate something like "T void::*", that wouldn't help =
with interfacing with lower-level code that continues to work with structur=
e offsets. I think the best way is to fix the minor wart with offsetof, th=
en say, "but look, here's a much better C++ way to do it!" with "T void::*"=
or whatever the syntax will be.
Given reinterpret_cast between size_t and PTM types, you can interoperate t=
he C and C++ solutions. I don=E2=80=99t see why that shouldn=E2=80=99t work=
.. You can even try it now, by casting to reference type.
--=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=_A2AC0D46-F1AC-4FE5-8E12-1CD8EA3FC4B4
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=
=3Dutf-8"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3D=
utf-8"><meta http-equiv=3D"Content-Type" content=3D"text/html charset=3Dutf=
-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; =
-webkit-line-break: after-white-space;" class=3D""><br class=3D""><div clas=
s=3D""><blockquote type=3D"cite" class=3D""><div class=3D"">On 2015=E2=80=
=9305=E2=80=9320, at 4:22 AM, Myriachan <<a href=3D"mailto:myriachan@gma=
il.com" class=3D"">myriachan@gmail.com</a>> wrote:</div><br class=3D"App=
le-interchange-newline"><div class=3D""><span style=3D"font-family: Helveti=
ca; font-size: 12px; font-style: normal; font-variant: normal; font-weight:=
normal; letter-spacing: normal; line-height: normal; orphans: auto; text-a=
lign: start; text-indent: 0px; text-transform: none; white-space: normal; w=
idows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none=
; display: inline !important;" class=3D"">As much as I'd appreciate somethi=
ng like "T void::*", that wouldn't help with interfacing with lower-level c=
ode that continues to work with structure offsets. I think the best w=
ay is to fix the minor wart with offsetof, then say, "but look, here's a mu=
ch better C++ way to do it!" with "T void::*" or whatever the syntax will b=
e.</span><br style=3D"font-family: Helvetica; font-size: 12px; font-style: =
normal; font-variant: normal; font-weight: normal; letter-spacing: normal; =
line-height: normal; orphans: auto; text-align: start; text-indent: 0px; te=
xt-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -=
webkit-text-stroke-width: 0px;" class=3D""></div></blockquote></div><br cla=
ss=3D""><div class=3D"">Given <font face=3D"Courier" class=3D"">reinte=
rpret_cast</font> between <font face=3D"Courier" class=3D"">size_t</fo=
nt> and PTM types, you can interoperate the C and C++ solutions. I don=E2=
=80=99t see why that shouldn=E2=80=99t work. You can even try it now, by ca=
sting to reference type.</div></body></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=_A2AC0D46-F1AC-4FE5-8E12-1CD8EA3FC4B4--
.
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 19 May 2015 19:12:39 -0700 (PDT)
Raw View
------=_Part_3418_1598605813.1432087959835
Content-Type: multipart/alternative;
boundary="----=_Part_3419_599991474.1432087959835"
------=_Part_3419_599991474.1432087959835
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 6:10:23 PM UTC-7, Nicol Bolas wrote:
>
> Do you know of compilers that implement classes, such that the offset from
> a pointer to type T to any non-virtual base member is *not* a
> compile-time constant? If all compilers implement classes such that the
> non-virtual-base members of any particular class have a consistent byte
> offset, then you don't need this classification at all. The only thing you
> need is a new version of `offsetof` that can take any type/member pair, so
> long as the member is in a virtual base of the type.
>
>
No, I'm not aware of any such implementations. I think that offsetof()
fails on some compilers that don't strictly enforce the rules if attempted
on a class with virtual bases, even if the chosen member is not a member of
one of the virtual bases...?
Is your choice of excluding all polymorphic types based on actual knowledge
> of how compilers work? Or is it based on something else?
>
No, it's based on what I've tried to interpret of the Standard, and from
various discussions of the topic on these mailing lists. In particular,
the exclusion of classes with virtual functions was because of objections
raised in a previous thread, particularly by Thiago, if my memory is
correct. His (I think) point of view on the matter made sense to me--the
Standard does not specify how virtual dispatch works, and crazy
implementations are legal, so all bets are off when it comes to classes
with virtual functions. Classes with virtual bases, of course, go crazy in
both theory and in reality.
> Note that these compilers did have lots of differences. Of particular note
> were variances between where the base class goes relative to the derived.
> On one platform, it was after, while on the others, it was before.
>
> And yet, at no time were there non-static offsets for members of
> polymorphic types.
>
Yes, that may be true, but the Standard does not appear to exclude this
possibility. The Standard does not even explicitly exclude this
possibility for trivially-copyable types, but that proof earlier in the
thread shows that this exclusion can be derived. The exclusion should
probably be stated for clarity, in my opinion; "consistent-layout" would do
this.
> So do you have actual experience with actual compilers that show that
> compilers will have variances regarding polymorphic types? If you haven't
> done the research, then my first suggestion would be to actually do the
> research and find out where the *real* intersection of your features E&F
> are. Not merely to think you know it, but to actually know where that
> intersection is in actual, live compilers.
>
> Also, from the examples you've given, I smell some kind of horrible
> serialization system behind this request, one that uses byte offsets and
> such to serialize members and so forth, rather than being hard-coded to the
> member names. My concern there is that reflection will basically do
> everything you need, and do it better, in a way that won't require this
> kind of low-level fiddling.
>
No, it's actually not about that. It's about having a meaningful low-level
memory layout for classes. This sort of thing is used for custom container
classes for optimization, and also to interface with C code or operating
system calls.
I have no reason to expect that E (offsetof) will fail on any compiler (in
concept, though it may fail due to enforcement of 18.2/4's undefined
behavior as a hard error).
F (indirect access to members via char array) might fail on a compiler due
to pointer aliasing and arithmetic weirdness with a few rules that I think
should be changed. If instead the class is part of a union with a char
array of the same size, and the constructor is called appropriately, then I
expect F to always work. The pointer arithmetic of accessing that array
through the offset may be currently undefined due to some ambiguities of
the Standard (e.g. Core errata 1701), but no compiler I know of has
problems with this, because char pointers are allowed to alias.
This would also explain why you're willing to sacrifice polymorphic types
> entirely. Reconstructing such data from a serialized object would be very
> difficult. So your serialization system would consider it out of scope.
> Thus, it's not part of your proposal.
>
> If so, maybe it would be better to wait for the right solution
> (reflection) than to modify the standard in such a way. I would hate for
> the committee to standardize something, only for another feature to come
> along and make it a moot point (re: std::bind. Good idea at the time, dumb
> idea with lambdas around).
>
I completely agree with this. It would be insane to try to implement
reflection as a hack involving offsets rather than get a real
implementation of reflection. But that's not what I'm trying to do.
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_3419_599991474.1432087959835
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 6:10:23 PM UTC-7, Nicol Bolas =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">Do you =
know of compilers that implement classes, such that the offset from a point=
er to type T to any non-virtual base member is <i>not</i> a compile-time co=
nstant? If all compilers implement classes such that the non-virtual-base m=
embers of any particular class have a consistent byte offset, then you don'=
t need this classification at all. The only thing you need is a new version=
of `offsetof` that can take any type/member pair, so long as the member is=
in a virtual base of the type.<br><div><br></div></div></blockquote><div><=
br>No, I'm not aware of any such implementations. I think that offset=
of() fails on some compilers that don't strictly enforce the rules if attem=
pted on a class with virtual bases, even if the chosen member is not a memb=
er of one of the virtual bases...?<br><br><br></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"><div>Is your choice of excluding all=
polymorphic types based on actual knowledge of how compilers work? Or is i=
t based on something else?<br></div></div></blockquote><div><br>No, it's ba=
sed on what I've tried to interpret of the Standard, and from various discu=
ssions of the topic on these mailing lists. In particular, the exclus=
ion of classes with virtual functions was because of objections raised in a=
previous thread, particularly by Thiago, if my memory is correct. Hi=
s (I think) point of view on the matter made sense to me--the Standard does=
not specify how virtual dispatch works, and crazy implementations are lega=
l, so all bets are off when it comes to classes with virtual functions.&nbs=
p; Classes with virtual bases, of course, go crazy in both theory and in re=
ality.<br><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>Note that these compilers did have lots of differences. O=
f particular note were variances between where the base class goes relative=
to the derived. On one platform, it was after, while on the others, it was=
before.<br><br>And yet, at no time were there non-static offsets for membe=
rs of polymorphic types.<br></div></div></blockquote><div><br>Yes, that may=
be true, but the Standard does not appear to exclude this possibility.&nbs=
p; The Standard does not even explicitly exclude this possibility for trivi=
ally-copyable types, but that proof earlier in the thread shows that this e=
xclusion can be derived. The exclusion should probably be stated for =
clarity, in my opinion; "consistent-layout" would do this.<br><br> </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></blockquote><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>So do you have actual experience with actual compilers that s=
how that compilers will have variances regarding polymorphic types? If you =
haven't done the research, then my first suggestion would be to actually do=
the research and find out where the <i>real</i> intersection of your featu=
res E&F are. Not merely to think you know it, but to actually know wher=
e that intersection is in actual, live compilers.<br><br>Also, from the exa=
mples you've given, I smell some kind of horrible serialization system behi=
nd this request, one that uses byte offsets and such to serialize members a=
nd so forth, rather than being hard-coded to the member names. My concern t=
here is that reflection will basically do everything you need, and do it be=
tter, in a way that won't require this kind of low-level fiddling.<br></div=
></div></blockquote><div><br>No, it's actually not about that. It's a=
bout having a meaningful low-level memory layout for classes. This so=
rt of thing is used for custom container classes for optimization, and also=
to interface with C code or operating system calls.<br><br>I have no reaso=
n to expect that E (offsetof) will fail on any compiler (in concept, though=
it may fail due to enforcement of 18.2/4's undefined behavior as a hard er=
ror).<br><br>F (indirect access to members via char array) might fail on a =
compiler due to pointer aliasing and arithmetic weirdness with a few rules =
that I think should be changed. If instead the class is part of a uni=
on with a char array of the same size, and the constructor is called approp=
riately, then I expect F to always work. The pointer arithmetic of ac=
cessing that array through the offset may be currently undefined due to som=
e ambiguities of the Standard (e.g. Core errata 1701), but no compiler I kn=
ow of has problems with this, because char pointers are allowed to alias.<b=
r><br><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"lt=
r"><div>This would also explain why you're willing to sacrifice polymorphic=
types entirely. Reconstructing such data from a serialized object would be=
very difficult. So your serialization system would consider it out of scop=
e. Thus, it's not part of your proposal.<br><br>If so, maybe it would be be=
tter to wait for the right solution (reflection) than to modify the standar=
d in such a way. I would hate for the committee to standardize something, o=
nly for another feature to come along and make it a moot point (re: std::bi=
nd. Good idea at the time, dumb idea with lambdas around).<br></div></div><=
/blockquote><div><br>I completely agree with this. It would be insane=
to try to implement reflection as a hack involving offsets rather than get=
a real implementation of reflection. But that's not what I'm trying =
to do.<br><br>Melissa<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_3419_599991474.1432087959835--
------=_Part_3418_1598605813.1432087959835--
.
Author: Myriachan <myriachan@gmail.com>
Date: Tue, 19 May 2015 19:46:03 -0700 (PDT)
Raw View
------=_Part_227_57573587.1432089963573
Content-Type: multipart/alternative;
boundary="----=_Part_228_1271635559.1432089963573"
------=_Part_228_1271635559.1432089963573
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 6:28:52 PM UTC-7, Thiago Macieira wrote:
>
> On Tuesday 19 May 2015 17:12:04 Myriachan wrote:
> > F: A data member of a class instance may be accessed by aliasing the
> class
> > with a char pointer and adding the member's offset.
>
> I don't think we need to create a new type for this. Simply change 18.2
> [support.types] p4:
>
> - If type is not a standard-layout class (Clause 9), the results are
> undefined.
> + If type is not a standard-layout or trivially copyable class (Clause 9),
> the
> results are undefined.
>
> Or refer to the contiguous storage definition from 1.8/5 that you quoted.
>
That wouldn't cover the use of offsetof() in non-trivially-copyable
non-standard-layout types, but is an improvement.
>
> I personally don't think we should overcomplicate this because offsetof is
> supposed to be low-level C code. C code shouldn't be dealing with more
> complex
> C++ types -- for that, we can have a C++ solution, including the
> subtraction
> operator with pointer-to-members.
>
> struct S
> {
> int i;
> };
> void f()
> {
> S s{0};
> auto pm1 = &S::i;
> int *p1 = pm1 - &s;
>
> *p1 = 1;
> assert(s.i == 1);
> }
>
> This bypasses the need for F.
>
What does this new subtraction operator do? Like, how does "pm1 - &s"
differ from "&(s.*pm1)"?
Also, keep in mind that to truly replace offsetof(), member pointers would
need to gain the ability to refer to members of members.
struct Kitty
{
char asdf;
double fdsa;
};
struct Meow
{
Kitty kitty;
};
double Meow::*member = &Meow::kitty.fdsa; // currently ill-formed
std::size_t offset = offsetof(Meow, kitty.fdsa); // extension accepted by
the compilers I use
The reason for F is to me quite important: it solidifies the existing
practice of treating classes as existing in memory as bytes. If you're
allowed to determine the offset, you should be allowed to use the offset.
Allowing aliasing a class with a char pointer and using the offset to a
member as the index is how to do that. It also resolves Core errata
1701--accessing a class's members through the array is defined in a
straightforward manner, as is (un)defining what happens regarding accessing
the dead space areas of a class.
template <type Member, typename Outer> ptrdiff_t
> make_offset(Outer *object, Member Outer::
> *pointer_to_member);
> template <type Member, typename Outer> Member Outer::*
> make_pointer_to_member(Outer *object, ptrdiff_t offset);
>
> On quite a few ABIs, the pointer to member *is* an offset anyway and those
> two
> functions would ignore the first argument and return a reinterpreted
> second
> argument.
>
>
I'd love for these to exist, irrespective of anything else I've mentioned.
=) It's possible to make this as a third-party library, if you do some
platform-specific hacks and maybe restrict the types people are allowed to
use, but if implemented by the compiler vendor, it'd work great.
What would the first parameter be used for? Something like, "the returned
member pointer shall only be used with objects of the same dynamic type as
the dynamic type of 'object', else the behavior is undefined"?
Member pointers are better than offsetof(), but offsetof() shouldn't be
locked out.
Love all your input, and thanks,
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
------=_Part_228_1271635559.1432089963573
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 6:28:52 PM UTC-7, Thiago Macie=
ira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Tuesday 19 May 20=
15 17:12:04 Myriachan wrote:
<br>> F: A data member of a class instance may be accessed by aliasing t=
he class=20
<br>> with a char pointer and adding the member's offset.
<br><br>I don't think we need to create a new type for this. Simply change =
18.2=20
<br>[support.types] p4:
<br>
<br>- If type is not a standard-layout class (Clause 9), the results =
are=20
<br>undefined.
<br>+ If type is not a standard-layout or trivially copyable class (Clause =
9), the=20
<br>results are undefined.
<br>
<br>Or refer to the contiguous storage definition from 1.8/5 that you quote=
d.
<br></blockquote><div><br>That wouldn't cover the use of offsetof() in non-=
trivially-copyable non-standard-layout types, but is an improvement.<br>&nb=
sp;</div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>I personally don't think we should overcomplicate this because offsetof=
is=20
<br>supposed to be low-level C code. C code shouldn't be dealing with more =
complex=20
<br>C++ types -- for that, we can have a C++ solution, including the subtra=
ction=20
<br>operator with pointer-to-members.
<br>
<br>struct S
<br>{
<br> int i;
<br>};
<br>void f()
<br>{
<br> S s{0};
<br> auto pm1 =3D &S::i;
<br> int *p1 =3D pm1 - &=
s;
<br>
<br> *p1 =3D 1;
<br> assert(s.i =3D=3D 1);
<br>}
<br>
<br>This bypasses the need for F.
<br></blockquote><div><br>What does this new subtraction operator do? =
Like, how does "<span style=3D"font-family: courier new,monospace;">pm1 - =
&s</span>" differ from "<span style=3D"font-family: courier new,monospa=
ce;">&(s.*pm1)</span>"?<br><br>Also, keep in mind that to truly replace=
<span style=3D"font-family: courier new,monospace;">offsetof()</span>, mem=
ber pointers would need to gain the ability to refer to members of members.=
<br><br><div class=3D"prettyprint" style=3D"background-color: rgb(250, 250,=
250); border-color: rgb(187, 187, 187); border-style: solid; border-width:=
1px; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">stru=
ct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span>=
<span style=3D"color: #606;" class=3D"styled-by-prettify">Kitty</span><span=
style=3D"color: #000;" class=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-by-prettify"><br> </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">char</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"> asdf</span><span style=3D"color: =
#660;" class=3D"styled-by-prettify">;</span><span style=3D"color: #000;" cl=
ass=3D"styled-by-prettify"><br> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">double</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> fdsa</span><span style=3D"color: #660;" cla=
ss=3D"styled-by-prettify">;</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">};</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"><br></span><span style=3D"color: #008;" class=3D"styled-by-prettify">str=
uct</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #606;" class=3D"styled-by-prettify">Meow</span><span=
style=3D"color: #000;" class=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-by-prettify"><br> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Kitty</span><span style=3D"c=
olor: #000;" class=3D"styled-by-prettify"> kitty</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"styled-by-prettify">};</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br><br></span><span style=3D"color: #008;" class=3D"styled=
-by-prettify">double</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-prettify"=
>Meow</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::*</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify">member </spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span=
style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&</span><span style=3D"colo=
r: #606;" class=3D"styled-by-prettify">Meow</span><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">kitty</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">.</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">fdsa</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">;</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #800;" class=3D"styled-by-prettify">// currently =
ill-formed</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
<br>std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">::<=
/span><span style=3D"color: #000;" class=3D"styled-by-prettify">size_t offs=
et </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"> offsetof</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #606;" class=3D"styled-by-prettify">Meow</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> kitty</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">.</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">fdsa</span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify"> </span><span style=3D"color: #800;" class=3D"styled-by-prettify=
">// extension accepted by the compilers I use</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span></div></code></div><br><br>T=
he reason for F is to me quite important: it solidifies the existing=20
practice of treating classes as existing in memory as bytes. If you'r=
e allowed to determine the offset, you should be allowed to use the offset.=
Allowing aliasing a class with a char pointer and using the offset t=
o a member as the index is how to do that. It also resolves Core erra=
ta 1701--accessing a class's members through the array is defined in a stra=
ightforward manner, as is (un)defining what happens regarding accessing the=
dead space areas of a class.<br><br><br></div><blockquote class=3D"gmail_q=
uote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pad=
ding-left: 1ex;">
template <type Member, typena=
me Outer> ptrdiff_t
<br>  =
; make_offset(<wbr>Outer *object, Member Outer:: *po=
inter_to_member);
<br> template <type Membe=
r, typename Outer> Member Outer::*
<br>  =
; make_pointer_<wbr>to_member(Outer *object, ptrdiff=
_t offset);
<br>
<br>On quite a few ABIs, the pointer to member *is* an offset anyway and th=
ose two=20
<br>functions would ignore the first argument and return a reinterpreted se=
cond=20
<br>argument.
<br>
<br></blockquote><div><br>I'd love for these to exist, irrespective of anyt=
hing else I've mentioned. =3D) It's possible to make this as a third-=
party library, if you do some platform-specific hacks and maybe restrict th=
e types people are allowed to use, but if implemented by the compiler vendo=
r, it'd work great.<br><br>What would the first parameter be used for? =
; Something like, "the returned member pointer shall only be used with obje=
cts of the same dynamic type as the dynamic type of 'object', else the beha=
vior is undefined"?<br><br>Member pointers are better than offsetof(), but =
offsetof() shouldn't be locked out.<br><br>Love all your input, and thanks,=
<br></div><br>Melissa<br></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_228_1271635559.1432089963573--
------=_Part_227_57573587.1432089963573--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 May 2015 19:54:02 -0700 (PDT)
Raw View
------=_Part_3448_1326565974.1432090442203
Content-Type: multipart/alternative;
boundary="----=_Part_3449_419101864.1432090442204"
------=_Part_3449_419101864.1432090442204
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 10:12:40 PM UTC-4, Myriachan wrote:
>
> On Tuesday, May 19, 2015 at 6:10:23 PM UTC-7, Nicol Bolas wrote:
>>
>> Do you know of compilers that implement classes, such that the offset
>> from a pointer to type T to any non-virtual base member is *not* a
>> compile-time constant? If all compilers implement classes such that the
>> non-virtual-base members of any particular class have a consistent byte
>> offset, then you don't need this classification at all. The only thing you
>> need is a new version of `offsetof` that can take any type/member pair, so
>> long as the member is in a virtual base of the type.
>>
>>
> No, I'm not aware of any such implementations. I think that offsetof()
> fails on some compilers that don't strictly enforce the rules if attempted
> on a class with virtual bases, even if the chosen member is not a member of
> one of the virtual bases...?
>
>
> Is your choice of excluding all polymorphic types based on actual
>> knowledge of how compilers work? Or is it based on something else?
>>
>
> No, it's based on what I've tried to interpret of the Standard, and from
> various discussions of the topic on these mailing lists. In particular,
> the exclusion of classes with virtual functions was because of objections
> raised in a previous thread, particularly by Thiago, if my memory is
> correct. His (I think) point of view on the matter made sense to me--the
> Standard does not specify how virtual dispatch works, and crazy
> implementations are legal, so all bets are off when it comes to classes
> with virtual functions. Classes with virtual bases, of course, go crazy in
> both theory and in reality.
>
>
>
>> Note that these compilers did have lots of differences. Of particular
>> note were variances between where the base class goes relative to the
>> derived. On one platform, it was after, while on the others, it was before.
>>
>> And yet, at no time were there non-static offsets for members of
>> polymorphic types.
>>
>
> Yes, that may be true, but the Standard does not appear to exclude this
> possibility. The Standard does not even explicitly exclude this
> possibility for trivially-copyable types, but that proof earlier in the
> thread shows that this exclusion can be derived. The exclusion should
> probably be stated for clarity, in my opinion; "consistent-layout" would do
> this.
>
That's why I mentioned the whole POD-to-standard layout thing. C++98/03
didn't specify
If what you want to do is standardize existing practice, you first need to
know what existing practice is. Arbitrarily deciding that existing practice
for compile-time layout stops at virtual functions seems... arbitrary.
>
>
>
>> So do you have actual experience with actual compilers that show that
>> compilers will have variances regarding polymorphic types? If you haven't
>> done the research, then my first suggestion would be to actually do the
>> research and find out where the *real* intersection of your features E&F
>> are. Not merely to think you know it, but to actually know where that
>> intersection is in actual, live compilers.
>>
>> Also, from the examples you've given, I smell some kind of horrible
>> serialization system behind this request, one that uses byte offsets and
>> such to serialize members and so forth, rather than being hard-coded to the
>> member names. My concern there is that reflection will basically do
>> everything you need, and do it better, in a way that won't require this
>> kind of low-level fiddling.
>>
>
> No, it's actually not about that. It's about having a meaningful
> low-level memory layout for classes.
>
The only times I ever cared about the low-level layout for memory in a
class were when I was:
* Heavily optimizing memory access patterns
* Performing serialization
* Needing to define a C++ type that was layout compatible with a C one.
If you're doing heavy optimization for memory access, you're more likely
trying to unbundle structs entirely. Also, base classes and the like are
probably not going to happen. We've already talked about serialization. And
the last one is covered by "standard layout" and specifically not part of
your proposal (see below for more).
So, can you give me an example of how this feature would help you with "low
level memory layout?"
This sort of thing is used for custom container classes for optimization,
> and also to interface with C code or operating system calls.
>
Well, here's one problem. The whole point of "standard layout" as a
separate type classification is that, if your class qualifies, then C++
guarantees that its layout follows C's layout rules. That's why it's
important, and that's why in certain code, you need to follow those rules.
Because if you do, you get to match C struct layout.
Merely having compile-time-determined offsets for members on types does not
mean that these offsets will match C's offsets for similarly constructed
types. E&F from your example are *not enough* to be able to "interface with
C code or operating system calls".
Indeed, your list of items proves that. You'd need at least A on that list
(order of definition = increasing offsets) before you could declare a C++
type to be layout compatible with a C type. Remember: non-standard layout
types are allowed to arbitrarily decide on the order of members. It could
sort them by typename in terms of order, and that would be legal.
Standard layout types cannot, because they're required to be
layout-compatible with C.
So what you have proposed doesn't solve at least part of the problem you
want it to solve.
I'm not sure what you mean by "custom container classes for optimization".
Nor am I sure how being able to get at a member by a static offset (which
as I understand the feature, is the only thing that "consistent layout"
does for you) would aid you in that way.
--
---
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_3449_419101864.1432090442204
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">On Tuesday, May 19, 2015 at 10:12:40 PM UTC-4, Myriachan w=
rote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8e=
x;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr">On Tuesd=
ay, May 19, 2015 at 6:10:23 PM UTC-7, Nicol Bolas 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">Do you know of compilers that imple=
ment classes, such that the offset from a pointer to type T to any non-virt=
ual base member is <i>not</i> a compile-time constant? If all compilers imp=
lement classes such that the non-virtual-base members of any particular cla=
ss have a consistent byte offset, then you don't need this classification a=
t all. The only thing you need is a new version of `offsetof` that can take=
any type/member pair, so long as the member is in a virtual base of the ty=
pe.<br><div><br></div></div></blockquote><div><br>No, I'm not aware of any =
such implementations. I think that offsetof() fails on some compilers=
that don't strictly enforce the rules if attempted on a class with virtual=
bases, even if the chosen member is not a member of one of the virtual bas=
es...?<br><br><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>Is your choice of excluding all polymorphic types based on actua=
l knowledge of how compilers work? Or is it based on something else?<br></d=
iv></div></blockquote><div><br>No, it's based on what I've tried to interpr=
et of the Standard, and from various discussions of the topic on these mail=
ing lists. In particular, the exclusion of classes with virtual funct=
ions was because of objections raised in a previous thread, particularly by=
Thiago, if my memory is correct. His (I think) point of view on the =
matter made sense to me--the Standard does not specify how virtual dispatch=
works, and crazy implementations are legal, so all bets are off when it co=
mes to classes with virtual functions. Classes with virtual bases, of=
course, go crazy in both theory and in reality.<br><br> </div><blockq=
uote 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>Note that these comp=
ilers did have lots of differences. Of particular note were variances betwe=
en where the base class goes relative to the derived. On one platform, it w=
as after, while on the others, it was before.<br><br>And yet, at no time we=
re there non-static offsets for members of polymorphic types.<br></div></di=
v></blockquote><div><br>Yes, that may be true, but the Standard does not ap=
pear to exclude this possibility. The Standard does not even explicit=
ly exclude this possibility for trivially-copyable types, but that proof ea=
rlier in the thread shows that this exclusion can be derived. The exc=
lusion should probably be stated for clarity, in my opinion; "consistent-la=
yout" would do this.<br></div></div></blockquote><div><br>That's why I ment=
ioned the whole POD-to-standard layout thing. C++98/03 didn't specify <br><=
br>If what you want to do is standardize existing practice, you first need =
to know what existing practice is. Arbitrarily deciding that existing pract=
ice for compile-time layout stops at virtual functions seems... arbitrary.<=
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><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></blockquote><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>So do you have actual experience with actual compile=
rs that show that compilers will have variances regarding polymorphic types=
? If you haven't done the research, then my first suggestion would be to ac=
tually do the research and find out where the <i>real</i> intersection of y=
our features E&F are. Not merely to think you know it, but to actually =
know where that intersection is in actual, live compilers.<br><br>Also, fro=
m the examples you've given, I smell some kind of horrible serialization sy=
stem behind this request, one that uses byte offsets and such to serialize =
members and so forth, rather than being hard-coded to the member names. My =
concern there is that reflection will basically do everything you need, and=
do it better, in a way that won't require this kind of low-level fiddling.=
<br></div></div></blockquote><div><br>No, it's actually not about that.&nbs=
p; It's about having a meaningful low-level memory layout for classes.</div=
></div></blockquote><div><br>The only times I ever cared about the low-leve=
l layout for memory in a class were when I was:<br><br>* Heavily optimizing=
memory access patterns<br>* Performing serialization<br>* Needing to defin=
e a C++ type that was layout compatible with a C one.<br><br>If you're doin=
g heavy optimization for memory access, you're more likely trying to unbund=
le structs entirely. Also, base classes and the like are probably not going=
to happen. We've already talked about serialization. And the last one is c=
overed by "standard layout" and specifically not part of your proposal (see=
below for more).<br><br>So, can you give me an example of how this feature=
would help you with "low level memory layout?"<br><br></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>This sort of thing is =
used for custom container classes for optimization, and also to interface w=
ith C code or operating system calls.<br></div></div></blockquote><div><br>=
Well, here's one problem. The whole point of "standard layout" as a separat=
e type classification is that, if your class qualifies, then C++ guarantees=
that its layout follows C's layout rules. That's why it's important, and t=
hat's why in certain code, you need to follow those rules. Because if you d=
o, you get to match C struct layout.<br><br>Merely having compile-time-dete=
rmined offsets for members on types does not mean that these offsets will m=
atch C's offsets for similarly constructed types. E&F from your example=
are <i>not enough</i> to be able to "interface with C code or operating sy=
stem calls".<br><br>Indeed, your list of items proves that. You'd need at l=
east A on that list (order of definition =3D increasing offsets) before you=
could declare a C++ type to be layout compatible with a C type. Remember: =
non-standard layout types are allowed to arbitrarily decide on the order of=
members. It could sort them by typename in terms of order, and that would =
be legal.<br><br>Standard layout types cannot, because they're required to =
be layout-compatible with C.<br><br>So what you have proposed doesn't solve=
at least part of the problem you want it to solve.<br><br>I'm not sure wha=
t you mean by "custom container classes for optimization". Nor am I sure ho=
w being able to get at a member by a static offset (which as I understand t=
he feature, is the only thing that "consistent layout" does for you) would =
aid you in that way.<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_3449_419101864.1432090442204--
------=_Part_3448_1326565974.1432090442203--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Tue, 19 May 2015 19:55:27 -0700 (PDT)
Raw View
------=_Part_3502_1513676921.1432090527568
Content-Type: multipart/alternative;
boundary="----=_Part_3503_1276728885.1432090527568"
------=_Part_3503_1276728885.1432090527568
Content-Type: text/plain; charset=UTF-8
On Tuesday, May 19, 2015 at 10:54:02 PM UTC-4, Nicol Bolas wrote:
>
> On Tuesday, May 19, 2015 at 10:12:40 PM UTC-4, Myriachan wrote:
>>
>> On Tuesday, May 19, 2015 at 6:10:23 PM UTC-7, Nicol Bolas wrote:
>>>
>>> Do you know of compilers that implement classes, such that the offset
>>> from a pointer to type T to any non-virtual base member is *not* a
>>> compile-time constant? If all compilers implement classes such that the
>>> non-virtual-base members of any particular class have a consistent byte
>>> offset, then you don't need this classification at all. The only thing you
>>> need is a new version of `offsetof` that can take any type/member pair, so
>>> long as the member is in a virtual base of the type.
>>>
>>>
>> No, I'm not aware of any such implementations. I think that offsetof()
>> fails on some compilers that don't strictly enforce the rules if attempted
>> on a class with virtual bases, even if the chosen member is not a member of
>> one of the virtual bases...?
>>
>>
>> Is your choice of excluding all polymorphic types based on actual
>>> knowledge of how compilers work? Or is it based on something else?
>>>
>>
>> No, it's based on what I've tried to interpret of the Standard, and from
>> various discussions of the topic on these mailing lists. In particular,
>> the exclusion of classes with virtual functions was because of objections
>> raised in a previous thread, particularly by Thiago, if my memory is
>> correct. His (I think) point of view on the matter made sense to me--the
>> Standard does not specify how virtual dispatch works, and crazy
>> implementations are legal, so all bets are off when it comes to classes
>> with virtual functions. Classes with virtual bases, of course, go crazy in
>> both theory and in reality.
>>
>>
>>
>>> Note that these compilers did have lots of differences. Of particular
>>> note were variances between where the base class goes relative to the
>>> derived. On one platform, it was after, while on the others, it was before.
>>>
>>> And yet, at no time were there non-static offsets for members of
>>> polymorphic types.
>>>
>>
>> Yes, that may be true, but the Standard does not appear to exclude this
>> possibility. The Standard does not even explicitly exclude this
>> possibility for trivially-copyable types, but that proof earlier in the
>> thread shows that this exclusion can be derived. The exclusion should
>> probably be stated for clarity, in my opinion; "consistent-layout" would do
>> this.
>>
>
> That's why I mentioned the whole POD-to-standard layout thing. C++98/03
> didn't specify
>
> If what you want to do is standardize existing practice, you first need to
> know what existing practice is. Arbitrarily deciding that existing practice
> for compile-time layout stops at virtual functions seems... arbitrary.
>
>
Sorry; ignore this part of my post. I forgot to delete this.
--
---
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_3503_1276728885.1432090527568
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><br><br>On Tuesday, May 19, 2015 at 10:54:02 PM UTC-4, Nic=
ol 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 Tuesday, May 19, 2015 at 10:12:40 PM UTC-4, Myriachan wrote:<blockquot=
e 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 Tuesday, May 19, 2015 at =
6:10:23 PM UTC-7, 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">Do you know of compilers that implement classes, such tha=
t the offset from a pointer to type T to any non-virtual base member is <i>=
not</i> a compile-time constant? If all compilers implement classes such th=
at the non-virtual-base members of any particular class have a consistent b=
yte offset, then you don't need this classification at all. The only thing =
you need is a new version of `offsetof` that can take any type/member pair,=
so long as the member is in a virtual base of the type.<br><div><br></div>=
</div></blockquote><div><br>No, I'm not aware of any such implementations.&=
nbsp; I think that offsetof() fails on some compilers that don't strictly e=
nforce the rules if attempted on a class with virtual bases, even if the ch=
osen member is not a member of one of the virtual bases...?<br><br><br></di=
v><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>Is your cho=
ice of excluding all polymorphic types based on actual knowledge of how com=
pilers work? Or is it based on something else?<br></div></div></blockquote>=
<div><br>No, it's based on what I've tried to interpret of the Standard, an=
d from various discussions of the topic on these mailing lists. In pa=
rticular, the exclusion of classes with virtual functions was because of ob=
jections raised in a previous thread, particularly by Thiago, if my memory =
is correct. His (I think) point of view on the matter made sense to m=
e--the Standard does not specify how virtual dispatch works, and crazy impl=
ementations are legal, so all bets are off when it comes to classes with vi=
rtual functions. Classes with virtual bases, of course, go crazy in b=
oth theory and in reality.<br><br> </div><blockquote class=3D"gmail_qu=
ote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div>Note that these compilers did have lots of=
differences. Of particular note were variances between where the base clas=
s goes relative to the derived. On one platform, it was after, while on the=
others, it was before.<br><br>And yet, at no time were there non-static of=
fsets for members of polymorphic types.<br></div></div></blockquote><div><b=
r>Yes, that may be true, but the Standard does not appear to exclude this p=
ossibility. The Standard does not even explicitly exclude this possib=
ility for trivially-copyable types, but that proof earlier in the thread sh=
ows that this exclusion can be derived. The exclusion should probably=
be stated for clarity, in my opinion; "consistent-layout" would do this.<b=
r></div></div></blockquote><div><br>That's why I mentioned the whole POD-to=
-standard layout thing. C++98/03 didn't specify <br><br>If what you want to=
do is standardize existing practice, you first need to know what existing =
practice is. Arbitrarily deciding that existing practice for compile-time l=
ayout stops at virtual functions seems... arbitrary.</div><br></div></block=
quote><div><br>Sorry; ignore this part of my post. I forgot to delete this.=
<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_3503_1276728885.1432090527568--
------=_Part_3502_1513676921.1432090527568--
.
Author: Thiago Macieira <thiago@macieira.org>
Date: Tue, 19 May 2015 21:09:25 -0700
Raw View
On Tuesday 19 May 2015 19:46:03 Myriachan wrote:
> > - If type is not a standard-layout class (Clause 9), the results are
> > undefined.
> > + If type is not a standard-layout or trivially copyable class (Clause 9),
> > the
> > results are undefined.
> >
> > Or refer to the contiguous storage definition from 1.8/5 that you quoted.
>
> That wouldn't cover the use of offsetof() in non-trivially-copyable
> non-standard-layout types, but is an improvement.
Indeed, but what's the use-case? Obviously there's no code doing that now. Why
do we need to enable that, instead of enabling a better alternative?
> What does this new subtraction operator do? Like, how does "pm1 - &s"
> differ from "&(s.*pm1)"?
It was proposed in a previous discussion. Let me take the example of offsetof
used in the "Linux kernel style list node": the offset of the member of type
"struct list" is used to recreate the original object. In other words, instead
of the traditional doubly-linked list
template <typename T> struct Node
{
T data;
Node *next, *prev;
};
You have:
struct Node { Node *next, *prev; };
struct MyType
{
[...]
Node list;
};
To obtain the next item of a given MyType object m, you get m->list->next and
then do pointer manipulation to get back from that to the containing MyType.
That could be C++ified as:
template <typename T, Node T:: *ListMember> T *next(T *item)
{
Node *nextNode = (item->*ListMember)->next;
return nextNode - ListMember;
}
We'd define the operations:
Outer *c;
MemberType *m;
MemberType ClassType:: *pm;
m = c + pm = &(c->*pm)
m - pm = c
pm = m - c (probably as a function, not an operator, since this
i already defined if MemberType and ClassType are the
same or related)
We could do this as a library solution if it weren't for the fact that we
can't define operator overloads for primitive types.
> Also, keep in mind that to truly replace offsetof(), member pointers would
> need to gain the ability to refer to members of members.
>
>
> struct Kitty
> {
> char asdf;
> double fdsa;
> };
> struct Meow
> {
char space[16];
> Kitty kitty;
> };
True, but you can compose the operation, but you'll need an intermediate stop
in the Kitty object. You can't fill a
double Meow:: *ptr
But we could define that:
Outer *c;
MemberType *m;
MemberType Inner:: *pm1;
Inner Outer:: *pm2;
MemberType Outer:: *composed;
m = c + pm2 + pm1 = &((c->*pm2)->*pm1)
m - pm1 = c + pm2
m - pm1 - pm2 = c
composed = pm2 + pm1
composed - pm1 = pm2
composed - pm2 = pm1
which is what allows for:
m = c + (pm2 + pm1)
In other words: we retain associativity of addition.
In the modified example, for the double member in a standard ABI, we'd have
pm1 = &Kitty::fdsa = 8
pm2 = &Meow::kitty = 16
composed = pm1 + pm2 = 24
pm2 = composed - pm1 = 24 - 8 = 16
pm1 = composed - pm2 = 24 - 16 = 8
With careful work, we may even maintain commutativity of addition:
template <typename Outer, typename Inner, typename MemberType>
MemberType Outer:: * operator +(MemberType Inner::*, Inner Outer::*);
template <typename Outer, typename Inner, typename MemberType>
MemberType Outer:: * operator +(Inner Outer::*, MemberType Inner::*);
Is there any case where the two above would be ambiguous? If Inner ==
MemberType or if Inner == Outer, it would be, but that would imply we have a
type containing itself as a member and that is not possible.
Can anyone see another ambiguity?
Obviously subtraction has never had commutativity, though we should be able to
reorder the operators:
pm1 - composed = 8 - 24 = -16
pm2 - composed = 16 - 24 = -8
This would create a "pointer-to-members" of type Outer Inner::* and Inner
MemberType::*. In other words, not a pointer to *member*, but pointer to
*container* and I think we should allow it. That in tur brings the unary
negation operator, which transforms a pointer-to-member in pointer-to-
container:
composed - pm1 = - (pm1 - composed)
The property of a pointer-to-container is that it can be applied on any object
of the container type, but needs to be applied to the correct member.
struct S { T i, j; } s1, s2;
S T::*ptc = - &S::i;
assert(&s1.i + ptc == &s1);
assert(&s2.i + ptc == &s2);
&s1.j + ptc; // undefined
Note how this also requires the type "S int::*" to exist
> > template <type Member, typename Outer> ptrdiff_t
> > make_offset(Outer *object, Member Outer::
> > *pointer_to_member);
> >
> > template <type Member, typename Outer> Member Outer::*
> > make_pointer_to_member(Outer *object, ptrdiff_t offset);
> >
> I'd love for these to exist, irrespective of anything else I've mentioned.
> =) It's possible to make this as a third-party library, if you do some
> platform-specific hacks and maybe restrict the types people are allowed to
> use, but if implemented by the compiler vendor, it'd work great.
Right. And so could all of the above I described, aside from actually using
operator+ and operator-.
> What would the first parameter be used for? Something like, "the returned
> member pointer shall only be used with objects of the same dynamic type as
> the dynamic type of 'object', else the behavior is undefined"?
I'm not sure. I know that in most ABIs it wouldn't be needed, since the
pointer to member encodes all of the information we need to transform it to an
offset. I added it without thinking too much, and I can't think of a reason why
it would be needed. We only need the type.
> Member pointers are better than offsetof(), but offsetof() shouldn't be
> locked out.
I disagree here. I think we shouldn't extend offsetof more.
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358
--
---
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/.
.