Is there any difference between the following three casts for extracting raw byte pointers for use in pointer arithmetic? (assume a platform where char is 1 byte.)
static_cast<char*>((void*)ptr))
reinterpret_cast<char*>(ptr)
- (updated) or:
static_cast<char*>(static_cast<void*>(ptr))
Which should I prefer?
In more detail...
Given pointers to two member objects in a class, I would like to compute an offset from one to the other, so that I can reconstruct the address of one member given an offset and the address of the other member.
// assumed data layout:
struct C {
// ...
A a;
// ...
B b;
}
The code that I use at the moment is along the lines of:
void approach1( A *pa, B *pb )
{
// compute offset:
std::ptrdiff_t offset = static_cast<char*>((void*)pa) - static_cast<char*>((void*)pb);
// then in some other function...
// given offset and ptr to b, compute ptr to a:
A *a = static_cast<A*>( (void*)(static_cast<char*>((void*)pb) + offset) );
}
main()
{
C c;
approach1(&c.a, &c.b);
}
I would like to know whether the following is better (or worse):
void approach2( A *pa, B *pb )
{
std::ptrdiff_t offset = reinterpret_cast<char*>(pa) - reinterpret_cast<char*>(pb);
// ...
A *a = reinterpret_cast<A*>( reinterpret_cast<char*>(pb) + offset );
}
Are the two methods entirely equivalent? Are they equally portable?
My impression is that approach1()
is more portable, because "static_cast
ing a pointer to and from void*
preserves the address," whereas reinterpret_cast<>
guarantees less (see accepted answer at link).
I would like to know what the cleanest way to do this is.
Update: Explanation of Purpose
A number of people have asked what is the purpose of computing these offsets. The purpose is to construct a meta-class table of instance offsets. This is used by a runtime reflection mechanism for automatic GUI building and persistance (the offsets are not serialized, just used to traverse the structure). The code has been in production for over 15 years. For the purposes of this question I just want to know the most portable way of computing the pointer offsets. I have no intention of making large changes to the way the metaclass system works. In addition, I'm also generally interested in the best way to do this, as I have other uses in mind (e.g. difference pointers for shared memory code).
NOTE: I can not use offsetof()
because in my actual code I only have the pointers to instances a
and b
, I don't necessarily have the type of the containing object c
or other static info to use offsetof()
. All I can assume is that a
and b
are members of the same object.