Use offsetof
from <cstddef>
, but beware it is only defined on standard-layout types (Live at Coliru):
Data* getBaseDataPtrFromString(std::string* mStringMember) {
static_assert(std::is_standard_layout<Data>::value,
"offsetof() only works on standard-layout types.");
return reinterpret_cast<Data*>(
reinterpret_cast<char*>(mStringMember) - offsetof(Data, b)
);
}
offsetof
is detailed in C++11 18.2/4:
The macro
offsetof
(type, member-designator) accepts a restricted set of type arguments in this International Standard. If type is not a standard-layout class (Clause 9), the results are undefined.195 The expressionoffsetof
(type, member-designator) is never type-dependent (14.6.2.2) and it is value-dependent (14.6.2.3) if and only if type is dependent. The result of applying theoffsetof
macro to a field that is a static data member or a function member is undefined. No operation invoked by theoffsetof
macro shall throw an exception andnoexcept(offsetof(type, member-designator))
shall betrue
.
and C99 (N1256) 7.17/3:
The macros are
NULL
which expands to an implementation-defined null pointer constant; and
offsetof(type, member-designator)
which expands to an integer constant expression that has type
size_t
, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that givenstatic type t;
then the expression
&(t.
member-designator)
evaluates to an address constant. (If the specified member is a bit-field, the behavior is undefined.)
The "restricted set of type arguments in this International Standard" in the C++ standard is there to draw your attention to the fact that offsetof
is more restrictive than is the case for the C standard.