Offset using pointer to member

D

Dave

Hello all,

For purposes of understanding the language better, I tried to determine the
offset of a struct member by using pointers to members (instead of something
such as the offsetof macro). However, if I understand correctly, this may
not be done portably. If I try to print a pointer to member, it just
converts to bool and I always get 1 (unless it's a null pointer to member).
There are no conversions from pointer to member to an integral type, so I
think I'm out of luck. Of course, I could hack the underlying
representation on my platform, but I want to be Standard-compliant...

Does anybody know of a way I can do what I want, or is my analysis correct
that it cannot be done portably?

Thanks,
Dave
 
G

Gianni Mariani

Dave said:
Hello all,

For purposes of understanding the language better, I tried to determine the
offset of a struct member by using pointers to members (instead of something
such as the offsetof macro). However, if I understand correctly, this may
not be done portably. If I try to print a pointer to member, it just
converts to bool and I always get 1 (unless it's a null pointer to member).
There are no conversions from pointer to member to an integral type, so I
think I'm out of luck. Of course, I could hack the underlying
representation on my platform, but I want to be Standard-compliant...

Does anybody know of a way I can do what I want, or is my analysis correct
that it cannot be done portably?


It's ugly but this should work.


template <typename T, typename V>
inline int MemberOffsetOf( V T::* v )
{
return ((int)&((( A* )0)->*v));
}



As for a compile-time version, you can't do it because you need to use
the "&" operator (address of) and this is apparently illegal in a
constant expression.

This is somthing like what it would look like for a compile-time
constant had the "&" operator been allowed.


template <typename T, typename V>
struct ClassValue
{
typedef T classtype;
typedef V valuetype;


template < V T::* P >
struct DoOffset
{
// & illegal here - sniff sniff ...
static const int offset = ( (int) & ( ( (T*) 0)->*P ) );
};


template <V T::* P>
char ( & SizeofThing() )[ DoOffset<P>::eek:ffset ];
};




template <typename T, typename V>
ClassValue< T, V > SizeofHelper( V T::* );


#define MemberOffsetOf( Member ) \
sizeof( SizeofHelper( Member ).SizeofThing< Member >() )
 
J

Jerry Coffin

It's ugly but this should work.
template <typename T, typename V>
inline int MemberOffsetOf( V T::* v )
{
return ((int)&((( A* )0)->*v));
}

Emphasis on _should_ here -- even though you and I know it's really
only doing compile-time math, this is still officially dereferencing a
null pointer, so officially it gives undefined behavior.
 
D

Dave

Jerry Coffin said:
Emphasis on _should_ here -- even though you and I know it's really
only doing compile-time math, this is still officially dereferencing a
null pointer, so officially it gives undefined behavior.

--
Later,
Jerry.

The universe is a figment of its own imagination.

Good point here! But interestingly, that same comment would also be true of
the way the C macro offsetof is typically implemented!
 
J

Jerry Coffin

Good point here! But interestingly, that same comment would also be
true of
the way the C macro offsetof is typically implemented!

That's true, but a bit different -- it's part of the implementation,
and the implementor is free to do things that only work on that
particular implementation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,817
Latest member
AdalbertoT

Latest Threads

Top