This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: how to compute offset of data member at compile time (virtual class)
- From: skaller <skaller at users dot sourceforge dot net>
- To: Andrew Haley <aph-gcc at littlepinkcloud dot COM>
- Cc: John Gateley <gateley at jriver dot com>, gcc-help at gcc dot gnu dot org
- Date: Fri, 26 Oct 2007 04:59:20 +1000
- Subject: Re: how to compute offset of data member at compile time (virtual class)
- References: <20071025111948.2369cb94.gateley@jriver.com> <18208.51943.281679.616922@zebedee.pink>
On Thu, 2007-10-25 at 17:57 +0100, Andrew Haley wrote:
> John Gateley writes:
> > I need to compute the offset of a data member at compile time.
> > The class has virtual functions, and so the offsetof macro does
> > not work (why?).
>
> Because it's a non-POD type. See Section 9, Classes:
An mistake by WG21.
> > Is there a way to do this?
>
> No. Consider what happens with multiple and virtual inheritance.
It is irrelevant. Given any struct, every data member has a fixed
offset within it. The following formula always calculates it:
typedef unsigned char uchar;
T x;
ptrdiff_t offsetof_m_in_T =
(uchar*)(void*)&x.m - (uchar*)(void*)&x
;
provided there are no access violations and no ambiguity.
Replacing 'x' with *(T*)0 isn't conforming but will usually
work :)
Note: with virtual bases, pointer to member *casts* can
be indeterminate, but there are no casts in offsetof:
the struct type is complete.
I use offsetof() on constructible types with virtual functions
extensively in Felix to calculate the offsets of every pointer
in every heap allocated data type. Thankfully gcc has a switch
now which allows this, -Wno-invalid-offsetof, because it is the
only way to get the information required, and the
information is mandatory for my garbage collector. It works fine
on MSVC++ too.
--
John Skaller <skaller at users dot sf dot net>
Felix, successor to C++: http://felix.sf.net