Topic: [offsetof-ext] Draft proposal for extended offsetof


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Mon, 24 Oct 2016 20:08:50 +0300
Raw View
Hi,

I've written a draft proposal for extending offsetof beyond
standard-layout classes:

https://github.com/Lastique/std-cxx-proposals/blob/master/extended-offsetof/extended-offsetof.md

Any comments and suggestions are welcome.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/3c3117b1-7944-1146-6a20-a0b2af612633%40gmail.com.

.


Author: Antony Polukhin <antoshkka@gmail.com>
Date: Mon, 24 Oct 2016 21:40:23 +0300
Raw View
2016-10-24 20:08 GMT+03:00 Andrey Semashev <andrey.semashev@gmail.com>:
> Hi,
>
> I've written a draft proposal for extending offsetof beyond standard-layout
> classes:
>
> https://github.com/Lastique/std-cxx-proposals/blob/master/extended-offsetof/extended-offsetof.md
>
> Any comments and suggestions are welcome.

I'd really love to have the offsetoff() to be usable at compile time.
Is it possible to make it a core constant expression?

--
Best regards,
Antony Polukhin

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAKqmYPb1sq6EK0JjDa04QcgiTE9UGJS%2B_BFVXAfDqpeaeNV9iw%40mail.gmail.com.

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Mon, 24 Oct 2016 22:17:00 +0300
Raw View
On Mon, Oct 24, 2016 at 9:40 PM, Antony Polukhin <antoshkka@gmail.com> wrote:
> 2016-10-24 20:08 GMT+03:00 Andrey Semashev <andrey.semashev@gmail.com>:
>> Hi,
>>
>> I've written a draft proposal for extending offsetof beyond standard-layout
>> classes:
>>
>> https://github.com/Lastique/std-cxx-proposals/blob/master/extended-offsetof/extended-offsetof.md
>>
>> Any comments and suggestions are welcome.
>
> I'd really love to have the offsetoff() to be usable at compile time.
> Is it possible to make it a core constant expression?

But offsetof already generates a constant expression. Or did I misunderstand?

I did think that offsetof should be a keyword rather than a macro,
although for different reasons. The problem with the macro is that
types with commas can be difficult to use with the macro:

  offsetof(std::pair< int, int >, second);

Here the macro would receive 3 arguments instead of 2.

I didn't add it into this proposal as I suspect it would make it more
difficult to get accepted. But a separate proposal that addresses this
problem would be useful.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6BFWUJdnYVSj1xVPjd5yXGrCYMFC56eTrG%3D4z45KnLD_A%40mail.gmail.com.

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 24 Oct 2016 12:55:00 -0700 (PDT)
Raw View
------=_Part_1549_2014049225.1477338900591
Content-Type: multipart/alternative;
 boundary="----=_Part_1550_1141260212.1477338900592"

------=_Part_1550_1141260212.1477338900592
Content-Type: text/plain; charset=UTF-8

On Monday, October 24, 2016 at 1:08:55 PM UTC-4, Andrey Semashev wrote:
>
> Hi,
>
> I've written a draft proposal for extending offsetof beyond
> standard-layout classes:
>
>
> https://github.com/Lastique/std-cxx-proposals/blob/master/extended-offsetof/extended-offsetof.md
>
> Any comments and suggestions are welcome.
>

Your motivating example raises a simple question.

If you truly want to transmit `B` across to another process... why *can't*
you rewrite it as a standard layout type?

struct standard_layout_B
{
    A a;
    int b;

    standard_layout_B(const B &old_b) : a(old_b), b(old_b.b) {}
    operator B() const {return B(...);}
};

Not only will this make it possible to do what you're attempting currently,
it will also make the layout more standard across compilers, thus making
the code more portable. After all, one compiler can put base classes after
derived classes, while another one puts them before them. And thus, to do
your interprocessing trick, you *must* use compilers that lay out trivially
copyable objects in the same way.

Whereas if you restrict yourself to standard layout, then the layout will
likely be portable to all compilers that use the same sizes/alignments for
basic types.

So it seems to me that `B` is just a poor interprocessing interface type.

The problem with your motivating example is that it is too easy to rewrite
in a way that makes it work currently. You should find a motivating example
where you're gaining something more than *convenience* by expanding
`offsetof` types.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/441bf0a3-23ba-4013-9ac6-dba15c78a243%40isocpp.org.

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

<div dir=3D"ltr">On Monday, October 24, 2016 at 1:08:55 PM UTC-4, Andrey Se=
mashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Hi,
<br>
<br>I&#39;ve written a draft proposal for extending offsetof beyond=20
<br>standard-layout classes:
<br>
<br><a href=3D"https://github.com/Lastique/std-cxx-proposals/blob/master/ex=
tended-offsetof/extended-offsetof.md" target=3D"_blank" rel=3D"nofollow" on=
mousedown=3D"this.href=3D&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2=
Fgithub.com%2FLastique%2Fstd-cxx-proposals%2Fblob%2Fmaster%2Fextended-offse=
tof%2Fextended-offsetof.md\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHbgS0h4Z=
M1GQiYi6d5FdR8SSYKRw&#39;;return true;" onclick=3D"this.href=3D&#39;https:/=
/www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2FLastique%2Fstd-cxx-prop=
osals%2Fblob%2Fmaster%2Fextended-offsetof%2Fextended-offsetof.md\x26sa\x3dD=
\x26sntz\x3d1\x26usg\x3dAFQjCNHbgS0h4ZM1GQiYi6d5FdR8SSYKRw&#39;;return true=
;">https://github.com/Lastique/<wbr>std-cxx-proposals/blob/master/<wbr>exte=
nded-offsetof/extended-<wbr>offsetof.md</a>
<br>
<br>Any comments and suggestions are welcome.
<br></blockquote><div><br>Your motivating example raises a simple question.=
<br><br>If you truly want to transmit `B` across to another process... why =
<i>can&#39;t</i> you rewrite it as a standard layout type?<br><br><div styl=
e=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187)=
; border-style: solid; border-width: 1px; overflow-wrap: break-word;" class=
=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprint">=
<span style=3D"color: #008;" class=3D"styled-by-prettify">struct</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> standard_layout_B<br=
></span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</span><=
span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 =
A a</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</span=
><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color: #008;" class=3D"styled-by-prettify">int</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> b</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"><br><br>=C2=A0 =C2=A0 standa=
rd_layout_B</span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>(</span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> B </span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">&amp;</span><span st=
yle=3D"color: #000;" class=3D"styled-by-prettify">old_b</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"> a</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">(</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y"></span><span style=3D"color: #660;" class=3D"styled-by-prettify"><code c=
lass=3D"prettyprint"><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">old_b</span><span style=3D"color: #660;" class=3D"styled-by-prettify"><=
/span></code>),</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"> b</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</=
span><code class=3D"prettyprint"><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify">old_b</span><span style=3D"color: #660;" class=3D"styled-by=
-prettify"></span></code><span style=3D"color: #660;" class=3D"styled-by-pr=
ettify">.b) {}</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>=C2=A0=C2=A0=C2=A0 operator B() const {return B(...);}<br>};<br></s=
pan></div></code></div><br>Not only will this make it possible to do what y=
ou&#39;re attempting currently, it will also make the layout more standard =
across compilers, thus making the code more portable. After all, one compil=
er can put base classes after derived classes, while another one puts them =
before them. And thus, to do your interprocessing trick, you <i>must</i> us=
e compilers that lay out trivially copyable objects in the same way.<br><br=
>Whereas if you restrict yourself to standard layout, then the layout will =
likely be portable to all compilers that use the same sizes/alignments for =
basic types.<br><br>So it seems to me that `B` is just a poor interprocessi=
ng interface type.<br><br>The problem with your motivating example is that =
it is too easy to rewrite in a way that makes it work currently. You should=
 find a motivating example where you&#39;re gaining something more than <i>=
convenience</i> by expanding `offsetof` types.<br></div></div>

<p></p>

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

------=_Part_1550_1141260212.1477338900592--

------=_Part_1549_2014049225.1477338900591--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Mon, 24 Oct 2016 23:23:13 +0300
Raw View
On Mon, Oct 24, 2016 at 10:55 PM, Nicol Bolas <jmckesson@gmail.com> wrote:
>
> Your motivating example raises a simple question.
>
> If you truly want to transmit `B` across to another process... why can't you
> rewrite it as a standard layout type?
>
> struct standard_layout_B
> {
>     A a;
>     int b;
>
>     standard_layout_B(const B &old_b) : a(old_b), b(old_b.b) {}
>     operator B() const {return B(...);}
> };

This solution is a possible workaround, but unfortunately just that.
The problem with it is that it breaks class hierarchy that would be
natural otherwise. The type conversion operator doesn't really fix it
because you still can't access A's members without explicitly
mentioning it in the code (or adding a bunch of forwarding functions).
That would complicate any generic code that is supposed to work with A
and all Bs.

> Not only will this make it possible to do what you're attempting currently,
> it will also make the layout more standard across compilers, thus making the
> code more portable. After all, one compiler can put base classes after
> derived classes, while another one puts them before them. And thus, to do
> your interprocessing trick, you must use compilers that lay out trivially
> copyable objects in the same way.

Binary layout of classes is mandated by ABI, which you can reasonably
expect to be supported by all compilers on the platform. Thus the
standard layout is not needed, unless you also plan to interface with
languages other than C++ (which I'm not).

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6DZDxj4x8YFNODhC009MTuMN_qpV%2BOWaJWy71DRJ0zNbw%40mail.gmail.com.

.


Author: Mikhail Maltsev <maltsevm@gmail.com>
Date: Mon, 24 Oct 2016 23:37:32 +0300
Raw View
On Mon, Oct 24, 2016 at 10:17 PM, Andrey Semashev
<andrey.semashev@gmail.com> wrote:
>
> I did think that offsetof should be a keyword rather than a macro,
> although for different reasons. The problem with the macro is that
> types with commas can be difficult to use with the macro:
>
>   offsetof(std::pair< int, int >, second);
>
> Here the macro would receive 3 arguments instead of 2.
>
> I didn't add it into this proposal as I suspect it would make it more
> difficult to get accepted. But a separate proposal that addresses this
> problem would be useful.

Note that GCC already implements offsetof as a built-in function:
https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html
Also, quoting https://gcc.gnu.org/ml/gcc-patches/2014-09/msg00705.html:
> even though offsetof on a non-standard-layout type is undefined, the usual expansion seems to be well-defined. So -Winvalid-offsetof should move to offsetof-specific code, and we can upgrade the warning to a pedwarn.

--
Regads,
   Mikhail Maltsev

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOqAUTg2cskvj0qDNHJR%3DwYUSx08hPUmOSHF4g2JaBPR4c4Now%40mail.gmail.com.

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Tue, 25 Oct 2016 00:20:09 +0300
Raw View
On Mon, Oct 24, 2016 at 11:37 PM, Mikhail Maltsev <maltsevm@gmail.com> wrote:
> On Mon, Oct 24, 2016 at 10:17 PM, Andrey Semashev
> <andrey.semashev@gmail.com> wrote:
>>
>> I did think that offsetof should be a keyword rather than a macro,
>> although for different reasons. The problem with the macro is that
>> types with commas can be difficult to use with the macro:
>>
>>   offsetof(std::pair< int, int >, second);
>>
>> Here the macro would receive 3 arguments instead of 2.
>>
>> I didn't add it into this proposal as I suspect it would make it more
>> difficult to get accepted. But a separate proposal that addresses this
>> problem would be useful.
>
> Note that GCC already implements offsetof as a built-in function:
> https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html

Yes, but that's not the case for all compilers. For instance, MSVC
implements it without an intrinsic.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAEhD%2B6CmGCkeaqLMyFR3kuoFRvgc9O5L4FB%2B%3DDfvnTSOYvQkAg%40mail.gmail.com.

.


Author: "T. C." <rs2740@gmail.com>
Date: Mon, 24 Oct 2016 15:18:05 -0700 (PDT)
Raw View
------=_Part_1278_691643924.1477347485256
Content-Type: multipart/alternative;
 boundary="----=_Part_1279_798926071.1477347485256"

------=_Part_1279_798926071.1477347485256
Content-Type: text/plain; charset=UTF-8



On Monday, October 24, 2016 at 5:20:11 PM UTC-4, Andrey Semashev wrote:
>
> On Mon, Oct 24, 2016 at 11:37 PM, Mikhail Maltsev <malt...@gmail.com
> <javascript:>> wrote:
> > On Mon, Oct 24, 2016 at 10:17 PM, Andrey Semashev
> > <andrey....@gmail.com <javascript:>> wrote:
> >>
> >> I did think that offsetof should be a keyword rather than a macro,
> >> although for different reasons. The problem with the macro is that
> >> types with commas can be difficult to use with the macro:
> >>
> >>   offsetof(std::pair< int, int >, second);
> >>
> >> Here the macro would receive 3 arguments instead of 2.
> >>
> >> I didn't add it into this proposal as I suspect it would make it more
> >> difficult to get accepted. But a separate proposal that addresses this
> >> problem would be useful.
> >
> > Note that GCC already implements offsetof as a built-in function:
> > https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html
>
> Yes, but that's not the case for all compilers. For instance, MSVC
> implements it without an intrinsic.
>

As Richard Smith noted in the other thread, with the new "conditionally
supported", an intrinsic is now required, because using it on unsupported
types requires a diagnostic.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/4c9df286-84c0-4416-9e56-b6fee213730e%40isocpp.org.

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

<div dir=3D"ltr"><br><br>On Monday, October 24, 2016 at 5:20:11 PM UTC-4, A=
ndrey Semashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Mon, O=
ct 24, 2016 at 11:37 PM, Mikhail Maltsev &lt;<a href=3D"javascript:" target=
=3D"_blank" gdf-obfuscated-mailto=3D"YrI7plHxAAAJ" rel=3D"nofollow" onmouse=
down=3D"this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.hre=
f=3D&#39;javascript:&#39;;return true;">malt...@gmail.com</a>&gt; wrote:
<br>&gt; On Mon, Oct 24, 2016 at 10:17 PM, Andrey Semashev
<br>&gt; &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailt=
o=3D"YrI7plHxAAAJ" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;javascr=
ipt:&#39;;return true;" onclick=3D"this.href=3D&#39;javascript:&#39;;return=
 true;">andrey....@gmail.com</a>&gt; wrote:
<br>&gt;&gt;
<br>&gt;&gt; I did think that offsetof should be a keyword rather than a ma=
cro,
<br>&gt;&gt; although for different reasons. The problem with the macro is =
that
<br>&gt;&gt; types with commas can be difficult to use with the macro:
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 offsetof(std::pair&lt; int, int &gt;, second);
<br>&gt;&gt;
<br>&gt;&gt; Here the macro would receive 3 arguments instead of 2.
<br>&gt;&gt;
<br>&gt;&gt; I didn&#39;t add it into this proposal as I suspect it would m=
ake it more
<br>&gt;&gt; difficult to get accepted. But a separate proposal that addres=
ses this
<br>&gt;&gt; problem would be useful.
<br>&gt;
<br>&gt; Note that GCC already implements offsetof as a built-in function:
<br>&gt; <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html" targe=
t=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.g=
oogle.com/url?q\x3dhttps%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOffsetof.=
html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHhhZETAF4u7jeOM8iCQP8tyKD37g&#=
39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOffsetof.html\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNHhhZETAF4u7jeOM8iCQP8tyKD37g&#39;;return true;=
">https://gcc.gnu.org/<wbr>onlinedocs/gcc/Offsetof.html</a>
<br>
<br>Yes, but that&#39;s not the case for all compilers. For instance, MSVC
<br>implements it without an intrinsic.
<br></blockquote><div><br></div><div>As Richard Smith noted in the other th=
read, with the new &quot;conditionally supported&quot;, an intrinsic is now=
 required, because using it on unsupported types requires a diagnostic.</di=
v><div><br></div></div>

<p></p>

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

------=_Part_1279_798926071.1477347485256--

------=_Part_1278_691643924.1477347485256--

.


Author: Nicol Bolas <jmckesson@gmail.com>
Date: Mon, 24 Oct 2016 15:19:15 -0700 (PDT)
Raw View
------=_Part_1422_1327091949.1477347555399
Content-Type: multipart/alternative;
 boundary="----=_Part_1423_1402716568.1477347555399"

------=_Part_1423_1402716568.1477347555399
Content-Type: text/plain; charset=UTF-8

On Monday, October 24, 2016 at 4:23:16 PM UTC-4, Andrey Semashev wrote:
>
> On Mon, Oct 24, 2016 at 10:55 PM, Nicol Bolas <jmck...@gmail.com
> <javascript:>> wrote:
> >
> > Your motivating example raises a simple question.
> >
> > If you truly want to transmit `B` across to another process... why can't
> you
> > rewrite it as a standard layout type?
> >
> > struct standard_layout_B
> > {
> >     A a;
> >     int b;
> >
> >     standard_layout_B(const B &old_b) : a(old_b), b(old_b.b) {}
> >     operator B() const {return B(...);}
> > };
>
> This solution is a possible workaround, but unfortunately just that.
> The problem with it is that it breaks class hierarchy that would be
> natural otherwise. The type conversion operator doesn't really fix it
> because you still can't access A's members without explicitly
> mentioning it in the code (or adding a bunch of forwarding functions).
> That would complicate any generic code that is supposed to work with A
> and all Bs.
>

I think you're kind of missing the point here.

If you're developing a system from scratch, you would develop it in a way
that would function with whatever interfaces you needed it to. So if you're
developing a type or types that needs to be interprocess-friendly, then you
would *start* by making them standard layout. You would then design your
system *around* that notion. So "any generic code" that is supposed to work
on such types would be designed to interpret them as standard layout.

So what we're talking about would be one of the following:

1: A and B are not under your control. Maybe they're legacy types, or maybe
they are types defined by some other system. But for whatever reason, you
are stuck with them as they are.

2: You have a genuine *need* for B to inherit from A, one which cannot be
satisfied by making `A` a member subobject of `B`.

For case 1, I would say that you're much better off creating an insulating
layer between types you don't control and the types the interprocessing
system has to deal with. As someone who has had dealings with network data
interchanges, I find that such layers make everyone on both sides much
happier.

If case 2 is your circumstance, then your example needs to actually outline
what that "genuine need" is. It needs to make it abundantly clear why
making the type standard layout is not a valid option. And your current
example does not, which is why it comes off as weak.

> Not only will this make it possible to do what you're attempting
> currently,
> > it will also make the layout more standard across compilers, thus making
> the
> > code more portable. After all, one compiler can put base classes after
> > derived classes, while another one puts them before them. And thus, to
> do
> > your interprocessing trick, you must use compilers that lay out
> trivially
> > copyable objects in the same way.
>
> Binary layout of classes is mandated by ABI, which you can reasonably
> expect to be supported by all compilers on the platform.


Is it? I've always acted under the belief that, on Windows at least, you
absolutely need to flatten everything at DLL boundaries because GCC and VS
have very different ideas about how class hierarchies are going to be put
together. Maybe I'm wrong here, but that was always how I understood it.
That Windows as a platform has a C ABI, but not one that fully defines all
of C++.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2aa81464-ac00-4b07-a9be-9486d389a599%40isocpp.org.

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

<div dir=3D"ltr">On Monday, October 24, 2016 at 4:23:16 PM UTC-4, Andrey Se=
mashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Mon, Oct 24, 2=
016 at 10:55 PM, Nicol Bolas &lt;<a href=3D"javascript:" target=3D"_blank" =
gdf-obfuscated-mailto=3D"fAJEZzbuAAAJ" rel=3D"nofollow" onmousedown=3D"this=
..href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39;jav=
ascript:&#39;;return true;">jmck...@gmail.com</a>&gt; wrote:
<br>&gt;
<br>&gt; Your motivating example raises a simple question.
<br>&gt;
<br>&gt; If you truly want to transmit `B` across to another process... why=
 can&#39;t you
<br>&gt; rewrite it as a standard layout type?
<br>&gt;
<br>&gt; struct standard_layout_B
<br>&gt; {
<br>&gt; =C2=A0 =C2=A0 A a;
<br>&gt; =C2=A0 =C2=A0 int b;
<br>&gt;
<br>&gt; =C2=A0 =C2=A0 standard_layout_B(const B &amp;old_b) : a(old_b), b(=
old_b.b) {}
<br>&gt; =C2=A0 =C2=A0 operator B() const {return B(...);}
<br>&gt; };
<br>
<br>This solution is a possible workaround, but unfortunately just that.
<br>The problem with it is that it breaks class hierarchy that would be
<br>natural otherwise. The type conversion operator doesn&#39;t really fix =
it
<br>because you still can&#39;t access A&#39;s members without explicitly
<br>mentioning it in the code (or adding a bunch of forwarding functions).
<br>That would complicate any generic code that is supposed to work with A
<br>and all Bs.<br></blockquote><div><br>I think you&#39;re kind of missing=
 the point here.<br><br>If you&#39;re developing a system from scratch, you=
 would develop it in a way that would function with whatever interfaces you=
 needed it to. So if you&#39;re developing a type or types that needs to be=
 interprocess-friendly, then you would <i>start</i> by making them standard=
 layout. You would then design your system <i>around</i> that notion. So &q=
uot;any generic code&quot; that is supposed to work on such types would be =
designed to interpret them as standard layout.<br><br>So what we&#39;re tal=
king about would be one of the following:<br><br>1: A and B are not under y=
our control. Maybe they&#39;re legacy types, or maybe they are types define=
d by some other system. But for whatever reason, you are stuck with them as=
 they are.<br><br>2: You have a genuine <i>need</i> for B to inherit from A=
, one which cannot be satisfied by making `A` a member subobject of `B`.<br=
><br>For case 1, I would say that you&#39;re much better off creating an in=
sulating layer between types you don&#39;t control and the types the interp=
rocessing system has to deal with. As someone who has had dealings with net=
work data interchanges, I find that such layers make everyone on both sides=
 much happier.<br><br>If case 2 is your circumstance, then your example nee=
ds to actually outline what that &quot;genuine need&quot; is. It needs to m=
ake it abundantly clear why making the type standard layout is not a valid =
option. And your current example does not, which is why it comes off as wea=
k.<br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
&gt; Not only will this make it possible to do what you&#39;re attempting c=
urrently,
<br>&gt; it will also make the layout more standard across compilers, thus =
making the
<br>&gt; code more portable. After all, one compiler can put base classes a=
fter
<br>&gt; derived classes, while another one puts them before them. And thus=
, to do
<br>&gt; your interprocessing trick, you must use compilers that lay out tr=
ivially
<br>&gt; copyable objects in the same way.
<br>
<br>Binary layout of classes is mandated by ABI, which you can reasonably
<br>expect to be supported by all compilers on the platform.</blockquote><d=
iv><br>Is it? I&#39;ve always acted under the belief that, on Windows at le=
ast, you absolutely need to flatten everything at DLL boundaries because GC=
C and VS have very different ideas about how class hierarchies are going to=
 be put together. Maybe I&#39;m wrong here, but that was always how I under=
stood it. That Windows as a platform has a C ABI, but not one that fully de=
fines all of C++.<br></div></div>

<p></p>

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

------=_Part_1423_1402716568.1477347555399--

------=_Part_1422_1327091949.1477347555399--

.


Author: Myriachan <myriachan@gmail.com>
Date: Mon, 24 Oct 2016 15:20:15 -0700 (PDT)
Raw View
------=_Part_4043_760561211.1477347616106
Content-Type: multipart/alternative;
 boundary="----=_Part_4044_752276645.1477347616106"

------=_Part_4044_752276645.1477347616106
Content-Type: text/plain; charset=UTF-8

On Monday, October 24, 2016 at 2:20:11 PM UTC-7, Andrey Semashev wrote:
>
> On Mon, Oct 24, 2016 at 11:37 PM, Mikhail Maltsev <malt...@gmail.com
> <javascript:>> wrote:
> > Note that GCC already implements offsetof as a built-in function:
> > https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html
>
> Yes, but that's not the case for all compilers. For instance, MSVC
> implements it without an intrinsic.
>

It's no longer possible to comply with the Standard without using an
intrinsic, because the current draft states that cases of offsetof() not
supported by the implementation are ill-formed, rather than undefined
behavior.  (There's another thread which discussed this.  Also, your
proposal does not change this.)

I have a few things to say about your proposal, though.

In the "Classes with virtual functions" section, you might want to note
that the existing draft and your proposal state that offsetof() can be
implemented on classes with virtual functions if the implementation
desires, because the rule says "conditionally-supported".

if the *member-designator* argument identifies a member *m* that is nested
> *N* levels deep in members *nN*, then the type of *ni* shall be a
> (possibly *cv*-qualified) stable-layout class or an array thereof, for 0
> <= *i* <= *N*.
>

This wording precludes something like struct A { int z[3]; }; offsetof(A,
z[2]), because "int" is not a "stable-layout class".  You should probably
define "stable-layout type" then use that in the rules.

With the notes about reference types, it is primarily because of
implementations of offsetof using reinterpret_cast mazes that reference
types aren't supported.  Something like __builtin_offsetof could support
reference types, in theory, when the member-designator's last element is
the only reference.  If a compiler intrinsic is now required in order to be
correct with offsetof(), supporting reference types isn't completely crazy,
though it is rather weird.  This apparent conflict should be resolved.

On Monday, October 24, 2016 at 11:40:26 AM UTC-7, Antony Polukhin
wrote:2016-10-24 20:08 GMT+03:00 Andrey Semashev <andrey....@gmail.com>:

> I'd really love to have the offsetoff() to be usable at compile time.
> Is it possible to make it a core constant expression?
>

offsetof() in C++ is inherited from C for the most part; in the C standard
it's already a constant expression.

Melissa

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/576c30c1-275a-4861-8c94-c11497078de4%40isocpp.org.

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

<div dir=3D"ltr">On Monday, October 24, 2016 at 2:20:11 PM UTC-7, Andrey Se=
mashev wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Mon, Oct 24, 2=
016 at 11:37 PM, Mikhail Maltsev &lt;<a href=3D"javascript:" target=3D"_bla=
nk" gdf-obfuscated-mailto=3D"YrI7plHxAAAJ" rel=3D"nofollow" onmousedown=3D"=
this.href=3D&#39;javascript:&#39;;return true;" onclick=3D"this.href=3D&#39=
;javascript:&#39;;return true;">malt...@gmail.com</a>&gt; wrote:
<br>&gt; Note that GCC already implements offsetof as a built-in function:
<br>&gt; <a href=3D"https://gcc.gnu.org/onlinedocs/gcc/Offsetof.html" targe=
t=3D"_blank" rel=3D"nofollow" onmousedown=3D"this.href=3D&#39;https://www.g=
oogle.com/url?q\x3dhttps%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOffsetof.=
html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHhhZETAF4u7jeOM8iCQP8tyKD37g&#=
39;;return true;" onclick=3D"this.href=3D&#39;https://www.google.com/url?q\=
x3dhttps%3A%2F%2Fgcc.gnu.org%2Fonlinedocs%2Fgcc%2FOffsetof.html\x26sa\x3dD\=
x26sntz\x3d1\x26usg\x3dAFQjCNHhhZETAF4u7jeOM8iCQP8tyKD37g&#39;;return true;=
">https://gcc.gnu.org/<wbr>onlinedocs/gcc/Offsetof.html</a>
<br>
<br>Yes, but that&#39;s not the case for all compilers. For instance, MSVC
<br>implements it without an intrinsic.
<br></blockquote><div><br>It&#39;s no longer possible to comply with the St=
andard without using an intrinsic, because the current draft states that ca=
ses of offsetof() not supported by the implementation are ill-formed, rathe=
r than undefined behavior.=C2=A0 (There&#39;s another thread which discusse=
d this.=C2=A0 Also, your proposal does not change this.)<br><br>I have a fe=
w things to say about your proposal, though.<br><br>In the &quot;Classes wi=
th virtual functions&quot; section, you might want to note that the existin=
g draft and your proposal state that offsetof() can be implemented on class=
es with virtual functions if the implementation desires, because the rule s=
ays &quot;conditionally-supported&quot;.<br><br><blockquote class=3D"gmail_=
quote" style=3D"margin: 0px 0px 0px 0.8ex; border-left: 1px solid rgb(204, =
204, 204); padding-left: 1ex;">if the <i>member-designator</i> argument ide=
ntifies a member <i>m</i> that is nested <i>N</i> levels deep in members <i=
>n<sub>N</sub></i>, then the type of <i>n<sub>i</sub></i> shall be a (possi=
bly <i>cv</i>-qualified) stable-layout class or an array thereof, for 0 &lt=
;=3D <i>i</i> &lt;=3D <i>N</i>.<br></blockquote><div><br>This wording precl=
udes something like struct A { int z[3]; }; offsetof(A, z[2]), because &quo=
t;int&quot; is not a &quot;stable-layout class&quot;.=C2=A0 You should prob=
ably define &quot;stable-layout type&quot; then use that in the rules.<br><=
br>With the notes about reference types, it is primarily because of impleme=
ntations of offsetof using reinterpret_cast mazes that reference types aren=
&#39;t supported.=C2=A0 Something like __builtin_offsetof could support ref=
erence types, in theory, when the member-designator&#39;s last element is t=
he only reference.=C2=A0 If a compiler intrinsic is now required in order t=
o be correct with offsetof(), supporting reference types isn&#39;t complete=
ly crazy, though it is rather weird.=C2=A0 This apparent conflict should be=
 resolved.<br></div><br>On Monday, October 24, 2016 at 11:40:26 AM UTC-7, A=
ntony Polukhin wrote:2016-10-24 20:08 GMT+03:00 Andrey Semashev &lt;<a targ=
et=3D"_blank" rel=3D"nofollow">andrey....@gmail.com</a>&gt;:
<br><blockquote class=3D"gmail_quote" style=3D"margin: 0px 0px 0px 0.8ex; b=
order-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">I&#39;d reall=
y love to have the offsetoff() to be usable at compile time.
<br>Is it possible to make it a core constant expression?
<br></blockquote><br>offsetof() in C++ is inherited from C for the most par=
t; in the C standard it&#39;s already a constant expression.<br><br>Melissa=
<br></div></div>

<p></p>

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

------=_Part_4044_752276645.1477347616106--

------=_Part_4043_760561211.1477347616106--

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Tue, 25 Oct 2016 14:08:30 +0300
Raw View
On 10/25/16 01:19, Nicol Bolas wrote:
>
> If you're developing a system from scratch, you would develop it in a
> way that would function with whatever interfaces you needed it to. So if
> you're developing a type or types that needs to be
> interprocess-friendly, then you would /start/ by making them standard
> layout. You would then design your system /around/ that notion. So "any
> generic code" that is supposed to work on such types would be designed
> to interpret them as standard layout.

I don't think so. When I start writing new code, I try to consider all
intended use cases for the classes. Interprocess interoperability is
surely one of them but the ability to work with classes with least
hassle in the surrounding code is also one of the factors. Readability
and design clarity are also important. So if IPC does not require me to
cross ABI boundary, or I can ensure that the involved ABIs are
compatible, there is no reason to limit my design with standard-layout
classes only. BTW, one of the side effects of my proposal is improved
formal portability of classes beyond standard-layout. That portability
is already there in practice, I just want the standard admit and
guarantee that.

> So what we're talking about would be one of the following:
>
> 1: A and B are not under your control. Maybe they're legacy types, or
> maybe they are types defined by some other system. But for whatever
> reason, you are stuck with them as they are.
>
> 2: You have a genuine /need/ for B to inherit from A, one which cannot
> be satisfied by making `A` a member subobject of `B`.
>
> For case 1, I would say that you're much better off creating an
> insulating layer between types you don't control and the types the
> interprocessing system has to deal with. As someone who has had dealings
> with network data interchanges, I find that such layers make everyone on
> both sides much happier.

You basically talk about serialization here. Serialization adds its
cost, both in development effort and runtime performance. That cost is
likely justified in network-based or file-based data exchange, but not
so much when exchange is only performed between local processes. I don't
want to pay that cost.

> If case 2 is your circumstance, then your example needs to actually
> outline what that "genuine need" is. It needs to make it abundantly
> clear why making the type standard layout is not a valid option. And
> your current example does not, which is why it comes off as weak.

There is no absolute "must" requirement for class inheritance - you've
shown a workaround before. However, that can be said about many other
things in C++, like lambdas, for example. These tools were introduced
because they improve some aspect of the language, like readability,
expressiveness, conciseness. Class inheritance (in general) is not a
feature that can't be lived without, the popularity of the C language
proves that. But it allows to express the intent more clear and
simplifies programming. To me, there is a great value in that.

I believe, the workaround you suggested will result in inferior code
surrounding the classes. The example I presented in the proposal was a
simplification from a real code that deals with audio and video exchange
between processes. There is a certain amount of metadata associated with
media frames; this metadata is organized in the following hierarchy:

   struct frame { long timestamp; };

   struct audio_frame : frame { ... };
   struct video_frame : frame { ... };

   struct raw_audio_frame : audio_frame { ... };
   struct encoded_audio_frame : audio_frame { ... };

   struct raw_video_frame : video_frame { ... };
   struct encoded_video_frame : video_frame { ... };

Imagine there are data in these classes and there are also more
specialized classes (e.g. for particular media codecs). If this
hierarchy was rewritten using only standard-layout classes, it would
look like this:

   struct frame { long timestamp; };

   struct audio_frame { frame f; ... };
   struct video_frame { frame f; ... };

   struct raw_audio_frame { audio_frame af; ... };
   struct encoded_audio_frame { audio_frame af; ... };

   struct raw_video_frame { video_frame vf; ... };
   struct encoded_video_frame { video_frame vf; ... };

Accessing the timestamp then would depend on the class you're working with:

   frame f;
   audio_frame af;
   video_frame vf;
   raw_audio_frame raf;
   encoded_audio_frame eaf;
   raw_video_frame rvf;
   encoded_video_frame evf;

   f.timestamp = 10;
   af.f.timestamp = 10;
   vf.f.timestamp = 10;
   raf.af.f.timestamp = 10;
   eaf.af.f.timestamp = 10;
   rvf.vf.f.timestamp = 10;
   evf.vf.f.timestamp = 10;

Clearly, this approach does not work for generic code and does not scale
well.

I will add a discussion of your suggested alternatives to the proposal,
thanks.

>     Binary layout of classes is mandated by ABI, which you can reasonably
>     expect to be supported by all compilers on the platform.
>
> Is it? I've always acted under the belief that, on Windows at least, you
> absolutely need to flatten everything at DLL boundaries because GCC and
> VS have very different ideas about how class hierarchies are going to be
> put together. Maybe I'm wrong here, but that was always how I understood
> it. That Windows as a platform has a C ABI, but not one that fully
> defines all of C++.

That is more or less the case with POSIX-like systems I worked with
(Linux, BSDs, OS X, Solaris). On Windows, there are two commonly used
ABI families (a family means a collection of ABIs for each supported
architecture): Microsoft's (supported by MSVC, Intel compiler and
clang-cl) and GCC's (used by MinGW and MinGW-w64; not sure about Cygwin,
but it should be considered a platform of its own anyway). The two ABIs
are different but compatible in many ways. For instance, `A`, `B` and
`C` classes from the proposal are binary compatible between MSVC and
MinGW (and GCC on Linux, too, while we're at it).

The main point I was making in the quoted part is that it is the ABI
what guarantees binary compatibility, and not the standard layout as
defined in C++. Even a structure as simple as `A` from the proposal can
be incompatible between two conforming C++ compilers because they chose
different representations of `int`. If you want your data structures to
be portable between compilers, you should be looking at their ABIs
first. If these ABIs are different, you analyse in what way they are
compatible and then limit your code to use only the subset of the
language features that is portable. Or just write serialization code
manually. Standard layout is of no help here, except as the set of
restrictions to achieve compatibility with C on the language level; it
does not guarantee binary compatibility, which is still in jurisdiction
of the ABI.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/677e8ab0-8c15-c719-6a76-9cc88b1f18ba%40gmail.com.

.


Author: Andrey Semashev <andrey.semashev@gmail.com>
Date: Tue, 25 Oct 2016 14:34:32 +0300
Raw View
On 10/25/16 01:20, Myriachan wrote:
> On Monday, October 24, 2016 at 2:20:11 PM UTC-7, Andrey Semashev wrote:
>
>     Yes, but that's not the case for all compilers. For instance, MSVC
>     implements it without an intrinsic.
>
> It's no longer possible to comply with the Standard without using an
> intrinsic, because the current draft states that cases of offsetof() not
> supported by the implementation are ill-formed, rather than undefined
> behavior.  (There's another thread which discussed this.  Also, your
> proposal does not change this.)

Ah, right, the diagnostic is required. Well, I suppose, that would be an
additional argument in favor of converting offsetof into a keyword.

> In the "Classes with virtual functions" section, you might want to note
> that the existing draft and your proposal state that offsetof() can be
> implemented on classes with virtual functions if the implementation
> desires, because the rule says "conditionally-supported".

Yes, that should also be obvious from the proposed wording. I'll update
that section.

>     if the /member-designator/ argument identifies a member /m/ that is
>     nested /N/ levels deep in members /n_N /, then the type of /n_i /
>     shall be a (possibly /cv/-qualified) stable-layout class or an array
>     thereof, for 0 <= /i/ <= /N/.
>
> This wording precludes something like struct A { int z[3]; };
> offsetof(A, z[2]), because "int" is not a "stable-layout class".

No, it doesn't. z[2] is not nested in a member in your example. The
proposed wording informally amounts to this:

If member-designator expands to n0.n1[10].n2.m then n0, n1 and n2 must
be stable-layout classes or arrays of such. m need not be a
stable-layout class.

That bullet point does not apply when member-designator is simply m.

That wording is somewhat contrived, I know, but I don't know how to
express the intent better in the standard language words, especially
since member-designator is not formally defined in C and I don't know
the proper naming of the n and m parts of it.

> With the notes about reference types, it is primarily because of
> implementations of offsetof using reinterpret_cast mazes that reference
> types aren't supported.  Something like __builtin_offsetof could support
> reference types, in theory, when the member-designator's last element is
> the only reference.  If a compiler intrinsic is now required in order to
> be correct with offsetof(), supporting reference types isn't completely
> crazy, though it is rather weird.  This apparent conflict should be
> resolved.

I can see two possible behaviors of offsetof with regard to references:

1. offsetof follows the reference and uses the address of the referred
object to calculate the offset. Not only this requires a runtime action
(you generally cannot know what object the reference is going to be
bound to), this results in a value that is completely not what offsetof
is intended for. Also, pointer arithmetics between unrelated objects is
currently not allowed, so both offsetof and using its returned value
would involve UB at some point.

2. offsetof does not follow the reference and returns an offset of a
hidden member that represents the reference. That is assuming there is
such hidden member (e.g. the compiler could remove the member if it is
able to safely replace its uses with the referred object). This
introduces the ability to take an address of a reference, something that
is now prohibited by the standard. I don't feel this is a good idea to
allow that; it would certainly require a good motivation to allow it,
and I don't have that motivation.

Since there is no sane behavior of offsetof wrt. references, the
proposal forbids them.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/6e0de419-569d-dc6b-b023-3bfe3220ff44%40gmail.com.

.