M
m0shbear
I have noticed that there are two basic types of pointers, from which
direct casting (reinterpret_cast) is impossible:
- T C::*
- T *
It looks like the difference between the two is, that in the former,
the pointer is defined as to being attached to a class.
In the latter, such a thing does not exist.
It seems that the compiler refuses to cast between the two because UD
ensues when you detach a pointer from its binding class or vice versa.
This means that any direct casts between the two will fail.
So it seems like the only ways to forcibly set the value for T (C::*x)
(...) are:
1) *reinterpret_cast<void**>(&x)
2) template<C> union pt { void *p; void (C::*q)();}; pt<C> p; p.q =
reinterpret_cast<void (C::*)()>(x);
// do something with p.p
x = reinterpret_cast<typeof(x)>(p.q);
The first one is more elegant but the second one is more useful when
you templatize overloaded cast operator ::*, as T C::* only works on
cast, not on assignment, so a dummy T C::* cannot be created. In this
case, pt<C>:
is set to the value that you want pt<C>::q to be, in
which case reinterpret_cast<T C::*>(pt<C>::q) returns the desired cast
of the value.
I am using this in order to create a proof-of-concept nullptr type
that matches a system's libc NULL, for some weird system that has
reinterpret_cast<int>(NULL) != 0, so that a weird NULL can be returned
as a normal 0 inside a wrapper function.
Which section of the ISO C++ spec defines this forbidden behavior?
Also, in which section of ISO C++ is it stated that any cast from 0 to
a pointer type shall work?
Unlike ISO 9899, the C++ spec's language is simply too complex for me
to read, kind of like the tax law. ISO 9899 had enough ambiguities and
complexities in it
direct casting (reinterpret_cast) is impossible:
- T C::*
- T *
It looks like the difference between the two is, that in the former,
the pointer is defined as to being attached to a class.
In the latter, such a thing does not exist.
It seems that the compiler refuses to cast between the two because UD
ensues when you detach a pointer from its binding class or vice versa.
This means that any direct casts between the two will fail.
So it seems like the only ways to forcibly set the value for T (C::*x)
(...) are:
1) *reinterpret_cast<void**>(&x)
2) template<C> union pt { void *p; void (C::*q)();}; pt<C> p; p.q =
reinterpret_cast<void (C::*)()>(x);
// do something with p.p
x = reinterpret_cast<typeof(x)>(p.q);
The first one is more elegant but the second one is more useful when
you templatize overloaded cast operator ::*, as T C::* only works on
cast, not on assignment, so a dummy T C::* cannot be created. In this
case, pt<C>:
which case reinterpret_cast<T C::*>(pt<C>::q) returns the desired cast
of the value.
I am using this in order to create a proof-of-concept nullptr type
that matches a system's libc NULL, for some weird system that has
reinterpret_cast<int>(NULL) != 0, so that a weird NULL can be returned
as a normal 0 inside a wrapper function.
Which section of the ISO C++ spec defines this forbidden behavior?
Also, in which section of ISO C++ is it stated that any cast from 0 to
a pointer type shall work?
Unlike ISO 9899, the C++ spec's language is simply too complex for me
to read, kind of like the tax law. ISO 9899 had enough ambiguities and
complexities in it