220 12677 <dedaddc6-c382-4256-83a9-6af4dbd91caf@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Myriachan <myriachan@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Usability extensions to offsetof
Date: Thu, 4 Sep 2014 12:19:38 -0700 (PDT)
Lines: 322
Approved: news@gmane.org
Message-ID: <dedaddc6-c382-4256-83a9-6af4dbd91caf@isocpp.org>
References: <fc4c748a-1805-4e92-ae3f-58bbfe6b7537@isocpp.org> <507AB10F-66B5-4E72-AF78-98B4AECBE6B3@gmail.com>
 <1790122.GP859xiMW3@tjmaciei-mobl4>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_3810_1726609344.1409858378802"
X-Trace: ger.gmane.org 1409858392 10461 80.91.229.3 (4 Sep 2014 19:19:52 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Thu, 4 Sep 2014 19:19:52 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDKLT4PURQHRBTPWUKQAKGQEIK3QELQ@isocpp.org Thu Sep 04 21:19:45 2014
Return-path: <std-proposals+bncBDKLT4PURQHRBTPWUKQAKGQEIK3QELQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ig0-f198.google.com ([209.85.213.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDKLT4PURQHRBTPWUKQAKGQEIK3QELQ@isocpp.org>)
	id 1XPcZL-0001jN-BF
	for gclcip-std-proposals@m.gmane.org; Thu, 04 Sep 2014 21:19:43 +0200
Original-Received: by mail-ig0-f198.google.com with SMTP id h18sf50564122igc.5
        for <gclcip-std-proposals@m.gmane.org>; Thu, 04 Sep 2014 12:19:42 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=V++WcqVkPHva1Sz6RIMJvEbZZit6nQyO3Ca4i3prMUA=;
        b=IYCs/DjBUsFs0FWx6G5mAiAjAyRJY2hsS8HyvC9shYB0tEVXeI2J5oBUsUXxA6jwsB
         Pb5Az5mp0CYqkumKACOP8HZcDcu8AuIwuFGATmDl8YOFy2YQ2pBtrfnCP6WcoCyJ7e7L
         LaveFJgy8WjaF+/DjrvePNAbFhHArQt2fhB9Gs9thiAuFXfhBGvkrBC9Pe6PcXAett9x
         v/p9m6fPzLWpxspOH452EmS5g5suFdXWeyl5B53IPzQyZtU/ZEnulhsXGwvh3MLjy3yW
         iBD+Gb9h4gMFbXuZQYWf8QDrYsgJ5K1sCvQjYb/q7MlBBsLExp56pQYzwjOu9ldg+Gfo
         87Xw==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=V++WcqVkPHva1Sz6RIMJvEbZZit6nQyO3Ca4i3prMUA=;
        b=ixcJkWolZPccxZUiXVLhp6zU5rDcCT7LyrTTqg6JxArEImuUawjKr1SO/77kudBEmr
         nCXYoXXEmC6QRFiOaIh8JsRhaWHMFWGzJNDM1aEjXdVt395XooGTkxWllAquDYJrARfM
         9Za3VJ9phx1UvLzNWlSiZ2gA0rvTVPGR3AY37ge57dnyPv0TcNk7gqyyJmB/+nY/SKZi
         Y1Cot0QFLve7JYU1la89Vgzj21TUakQdoXfKiHWmK7ul1yS6ivQbqNENTencNOBI6b/6
         jPLWJZpX9V97MgSPyJ5jQHJTyU6yQb3Tb/lWSEsE3xqIL3lnoYVPt4U8IF+QaT7D8GGd
         ru9g==
X-Gm-Message-State: ALoCoQnxRNVU9NK584KezIedH8+8MPbeZlJiVUh+LgBrZNsii2MhpRGgdREehyRCI7rmEMhiceKW
X-Received: by 10.50.33.18 with SMTP id n18mr3731178igi.8.1409858382379;
        Thu, 04 Sep 2014 12:19:42 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.50.143.76 with SMTP id sc12ls765059igb.3.gmail; Thu, 04 Sep
 2014 12:19:41 -0700 (PDT)
X-Received: by 10.50.41.103 with SMTP id e7mr128405igl.8.1409858381628;
        Thu, 04 Sep 2014 12:19:41 -0700 (PDT)
In-Reply-To: <1790122.GP859xiMW3@tjmaciei-mobl4>
X-Original-Sender: myriachan@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:12677
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/12677>

------=_Part_3810_1726609344.1409858378802
Content-Type: text/plain; charset=UTF-8

On Wednesday, September 3, 2014 9:03:07 AM UTC-7, Thiago Macieira wrote:
>
> On Wednesday 03 September 2014 12:46:39 David Krauss wrote: 
> > Where would you prefer to use offsetof, instead of a pointer-to-member? 
>
> In the calculation of the reverse: from member to top-of-object. 
>

This has been my experience as well: most of the time, the reason I want 
such functionality is because I want to return to the beginning of the 
object, to "undo" a member pointer.  In other words, Microsoft's 
CONTAINING_RECORD macro, but with member pointers.  It actually wasn't what 
prompted the idea *this* time, though.

template <class Source, class Member>
Source *containing_instance(Member *member, Member Source::*member_pointer)
{
    static_assert(is_object<Source>::value, "source class must be of object 
type");

    typedef typename conditional<is_const<Source>::value, const char, char
>::type c_char;
    typedef typename conditional<is_volatile<Source>::value, volatile c_char
, c_char>::type cv_char;

    ptrdiff_t offset = reinterpret_cast<cv_char *>(&(reinterpret_cast<Source 
*>(1)->*member_pointer)) -
        reinterpret_cast<cv_char *>(1);

    // I don't see how to do this without breaking aliasing rules...
    return reinterpret_cast<Source *>(reinterpret_cast<cv_char *>(member) - 
offset);
}


There isn't a Standard way of determining whether a class has virtual 
inheritance, however.  is_offsetof_compatible would help with this, and 
would be useful in more cases than merely standard-layout.  Although, 
actually, *are* there cases in which virtual inheritance breaks offsetof?

Member pointers also have a limitation in that you can't use them without a 
known base type.  If you have highly-generic code that can't be templated 
on the type, you'd need to have a base class in order to use member 
pointers.  Adding a base class means that you can no longer use 
aggregate-initialization of arrays of that class.  I ran into this exact 
problem last week at work, and it forcing me to use offsetof and lose all 
type safety prompted me to make this proposal.  (Conversion to an offset 
loses type safety, of course, but prior to that conversion, you have type 
safety.  Some is better than none, I figure.)


On Tuesday, September 2, 2014 9:46:44 PM UTC-7, David Krauss wrote:
>
> offsetof is a vestige of C compatibility, and standard layout is 
> specifically tailored to C ABI compatibility. So the restriction is 
> probably exactly what its designers intended.
>
>
Standard-layout exists for compatibility with other languages' in-memory 
structures, yes, but offsetof is useful under looser requirements.  
Standard-layout guarantees things like that the in-memory order matches the 
order of members, and that the offset of the first element is zero.  These 
need not be true to make use of offsetof in many cases.

However, even in the worst case, with virtual functions and virtual 
inheritance, it's always true that a class C's instance C *c occupies a 
"fixed" location starting at a char *p = reinterpret_cast<char *>(c) and 
ends right before p + sizeof(C).  Applied recursively, this means that for 
each data member M C::m there exists an offset o such that &c->m == 
reinterpret_cast<M *>(p + o).

Where would you prefer to use offsetof, instead of a pointer-to-member?
>  
>

Whenever a template won't work or is inconvenient - whenever you need to 
access a member of a class using a char *.  It can avoid code bloat, too, 
by avoiding a zillion copies of assembly code with tiny changes.  The 
purpose of such a feature would primarily be for libraries.  Users of such 
a library would specify an element using a member pointer, then the library 
itself would internally use offsets.  (Such a library could not exist as a 
DLL, because it is not possible in current C++ to use a member pointer with void 
*.  Instead, you have to use callback functions.)

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_3810_1726609344.1409858378802
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Wednesday, September 3, 2014 9:03:07 AM UTC-7, Thiago M=
acieira wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-l=
eft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On Wednesday 03 =
September 2014 12:46:39 David Krauss wrote:
<br>&gt; Where would you prefer to use offsetof, instead of a pointer-to-me=
mber?
<br>
<br>In the calculation of the reverse: from member to top-of-object.
<br></blockquote><br>This has been my experience as well: most of the time,=
 the reason I want such functionality is because I want to return to the be=
ginning of the object, to "undo" a member pointer.&nbsp; In other words, Mi=
crosoft's <span style=3D"font-family: courier new,monospace;">CONTAINING_RE=
CORD</span> macro, but with member pointers.&nbsp; It actually wasn't what =
prompted the idea <i>this</i> time, though.<br><br><div class=3D"prettyprin=
t" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 18=
7, 187); border-style: solid; border-width: 1px; word-wrap: break-word;"><c=
ode class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"colo=
r: #008;" class=3D"styled-by-prettify">template</span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">&lt;</span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">class</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styled-by-=
prettify">Source</span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </=
span><span style=3D"color: #008;" class=3D"styled-by-prettify">class</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #606;" class=3D"styled-by-prettify">Member</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">&gt;</span><span style=3D"co=
lor: #000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #=
606;" class=3D"styled-by-prettify">Source</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"style=
d-by-prettify">containing_instance</span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">(</span><span style=3D"color: #606;" class=3D"style=
d-by-prettify">Member</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">member<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #606;" class=3D"styled-by-prettify">Member</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #6=
06;" class=3D"styled-by-prettify">Source</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">::*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">member_pointer</span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"s=
tyled-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">{</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy"><br>&nbsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-b=
y-prettify">static_assert</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">is_object</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">&lt;</span><span style=3D"color: #606;" class=3D"styled-by-prettify">S=
ource</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;:=
:</span><span style=3D"color: #000;" class=3D"styled-by-prettify">value</sp=
an><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: #080;" class=3D"styled-by-prettify">"source class must be of object =
type"</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br><br>&nbsp=
; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify">t=
ypedef</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </s=
pan><span style=3D"color: #008;" class=3D"styled-by-prettify">typename</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> conditional</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">is_const</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span styl=
e=3D"color: #606;" class=3D"styled-by-prettify">Source</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify">value</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" cla=
ss=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"sty=
led-by-prettify">const</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettif=
y">char</span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">char</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify">type c_char</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"><br>&nbsp; &nbsp; </span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">typedef</span><span style=3D=
"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: #=
008;" class=3D"styled-by-prettify">typename</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> conditional</span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify">is_volatile</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #606;" class=
=3D"styled-by-prettify">Source</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">&gt;::</span><span style=3D"color: #000;" class=3D"styl=
ed-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=
"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">volatil=
e</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> c_char</=
span><span style=3D"color: #660;" class=3D"styled-by-prettify">,</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> c_char</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">&gt;::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">type cv_char</span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">;</span><span style=3D"col=
or: #000;" class=3D"styled-by-prettify"><br><br>&nbsp; &nbsp; ptrdiff_t off=
set </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #000;" class=3D"styled-by-prettify">cv_char </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">*&gt;(&amp;(</span><span=
 style=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span=
 style=3D"color: #606;" class=3D"styled-by-prettify">Source</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">*&gt;(</span><span style=3D"color: =
#066;" class=3D"styled-by-prettify">1</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">)-&gt;*</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">member_pointer</span><span style=3D"color: #660;" c=
lass=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>&nbsp; &nbsp; &nbsp; &nbsp; </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">reinterpret_cast</span><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">cv_char </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">*&gt;(</span><span style=3D"color: #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-prettif=
y"><br><br>&nbsp; &nbsp; </span><span style=3D"color: #800;" class=3D"style=
d-by-prettify">// I don't see how to do this without breaking aliasing rule=
s...</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>&n=
bsp; &nbsp; </span><span style=3D"color: #008;" class=3D"styled-by-prettify=
">return</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">reinterpret=
_cast</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;<=
/span><span style=3D"color: #606;" class=3D"styled-by-prettify">Source</spa=
n><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">*&gt;(</span><span style=
=3D"color: #008;" class=3D"styled-by-prettify">reinterpret_cast</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">cv_char </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">*&gt;(</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify">member</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"> offset</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">}</sp=
an></div></code></div><br><br>There isn't a Standard way of determining whe=
ther a class has virtual inheritance, however.&nbsp; <span style=3D"font-fa=
mily: courier new,monospace;">is_offsetof_compatible</span> would help with=
 this, and would be useful in more cases than merely standard-layout.&nbsp;=
 Although, actually, <i>are</i> there cases in which virtual inheritance br=
eaks <span style=3D"font-family: courier new,monospace;">offsetof</span>?<b=
r><br>Member pointers also have a limitation in that you can't use them=20
without a known base type.&nbsp; If you have highly-generic code that can't=
=20
be templated on the type, you'd need to have a base class in order to=20
use member pointers.&nbsp; Adding a base class means that you can no longer=
=20
use aggregate-initialization of arrays of that class.&nbsp; I ran into this=
=20
exact problem last week at work, and it forcing me to use <span style=3D"fo=
nt-family: courier new,monospace;">offsetof</span>
 and lose all type safety prompted me to make this proposal.&nbsp;=20
(Conversion to an offset loses type safety, of course, but prior to that
 conversion, you have type safety.&nbsp; Some is better than none, I figure=
..)<br><br><br>On Tuesday, September 2, 2014 9:46:44 PM UTC-7, David Krauss =
wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8=
ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div style=3D"word-wrap:=
break-word"><div><div><font face=3D"Courier">offsetof</font>
 is a vestige of C compatibility, and standard layout is specifically=20
tailored to C ABI compatibility. So the restriction is probably exactly=20
what its designers intended.</div><div><br></div></div></div></blockquote><=
div><br>Standard-layout exists for compatibility with other languages' in-m=
emory structures, yes, but <span style=3D"font-family: courier new,monospac=
e;">offsetof</span> is useful under looser requirements.&nbsp; Standard-lay=
out guarantees things like that the in-memory order matches the order of me=
mbers, and that the offset of the first element is zero.&nbsp; These need n=
ot be true to make use of <span style=3D"font-family: courier new,monospace=
;">offsetof</span> in many cases.<br><br>However, even in the worst case, w=
ith virtual functions and virtual inheritance, it's always true that a clas=
s <span style=3D"font-family: courier new,monospace;">C</span>'s instance <=
span style=3D"font-family: courier new,monospace;">C *c</span> occupies a "=
fixed" location starting at a <span style=3D"font-family: courier new,monos=
pace;">char *p =3D reinterpret_cast&lt;char *&gt;(c)</span> and ends right =
before <span style=3D"font-family: courier new,monospace;">p + sizeof(C)</s=
pan>.&nbsp; Applied recursively, this means that for each data member <span=
 style=3D"font-family: courier new,monospace;">M C::m</span> there exists a=
n offset <span style=3D"font-family: courier new,monospace;">o</span> such =
that <span style=3D"font-family: courier new,monospace;">&amp;c-&gt;m =3D=
=3D reinterpret_cast&lt;M *&gt;(p + o)</span>.<br><br></div><blockquote cla=
ss=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><div=
></div><div>Where would you prefer to use <font face=3D"Courier">offsetof</=
font>, instead of a pointer-to-member?</div>&nbsp;</div></div></blockquote>=
<br>Whenever a template won't work or is inconvenient - whenever you need t=
o access a member of a class using a <span style=3D"font-family: courier ne=
w,monospace;">char *</span>.&nbsp; It can avoid code bloat, too, by avoidin=
g a zillion copies of assembly code with tiny changes.&nbsp; The purpose of=
 such a feature would primarily be for libraries.&nbsp; Users of such a lib=
rary would specify an element using a member pointer, then the library itse=
lf would internally use offsets.&nbsp; (Such a library could not exist as a=
 DLL, because it is not possible in current C++ to use a member pointer wit=
h <span style=3D"font-family: courier new,monospace;">void *</span>.&nbsp; =
Instead, you have to use callback functions.)<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&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 />
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_3810_1726609344.1409858378802--

.
