null pointer to member
By chys on July 19th, 2009The most straightforward implementation of a pointer to member is to store the offset:
struct Struct
{
int a;
int b;
};
The internal value of &Struct::a is 0 and &Struct::b is sizeof(int).
This leads to the illusion that &Struct::a, a valid pointer, is equal to a null pointer. Not only does this violate the standard, but also breaks many codes existing in practice.
The current (pre-0x) orthodox method of defining a cast from user-defined class to bool is not using operator bool (which leads to some unwanted consequences), but something like this:
class MyClass
{
/* ....... */
struct BooleanConvert { int val; };
operator int BooleanConvert::* () const
{
return ( /* true */ ) ? &BooleanConvert::val : 0;
}
};
It is hard to read, but the idea is simple: return a valid pointer (to member) if true, a null pointer (to member) if false.
Q: It seems both pointers evaluate to 0. How do they distinguish them?
A: In practice, a null pointer to member is represented, internally, by a value of -1 instead of 0!
So,
#include <cstdio>
#include <cstddef>
using namespace std;
struct Struct
{
int a;
};
int main()
{
union
{
int Struct::*ptr;
void * val;
};
ptr = 0;
printf ("%p\n", val);
}
the above program would output 0xffffffff (32-bit systems).
Fortunately, this does not annoy. We can safely ignore this detail (except when writing a compiler, of coz..) It seems that, except using unions or brutal memory access, there is no way to convert pointers to member to/from integers and normal pointers. (C-style casts, reinterpret_cast, etc. all reject such conversions.)
Related posts:
Tags: C/C++
