Consider the following code:
struct A {
int n;
double d;
};
int main() {
auto a = A{.n = 1, .d = 3.14};
// error: static_cast from 'int*' to 'A*' is not allowed
auto _ = static_cast<A*>(&a.n);
}
See https://godbolt.org/z/8814sEh79
However, the documentation of static_cast
in cppref says: (emphasis mine)
Two objects a and b are pointer-interconvertible if:
- they are the same object, or
- one is a union object and the other is a non-static data member of that object, or
- one is a standard-layout class object and the other is the first non-static data member of that object or any base class subobject of that object, or
- there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.
According to the citation above, &a
and &a.n
should be pointer-interconvertible, so why is static_cast<A*>(&a.n)
ill-formed?
What you are referring to is §6.8.4 [basic.compound], paragraph 4:
Two objects a and b are pointer-interconvertible if:
[...]
—(4.3) one is a standard-layout class object and the other is the first non-static data member of that object or
[...]
However, static_cast
is not the tool for such a conversion, since for static_cast
to work, the types need to be related. in your case, they are not. int
is not related to A
and vice versa. the only way you can achieve what you want is using a double static_cast
over void*
:
static_cast<int*>(static_cast<void*>(a));
which is equivalent to reinterpret_cast
, which is the correct tool:
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (7.6.1.10)