ttwang@polyslo.CalPoly.EDU (Thomas Wang) (10/06/89)
I need to know the byte offset of 'header' in class 'foo' before any 'foo' object is allocated. class foo { public: int grr; int header; void alloc(); }; void foo::alloc() { cout << (&(this->header)) - this << "\n"; // bomb? } main() { ((foo*) 0) -> alloc(); // bomb? } Just how portable is this kind of code? -Thomas Wang ("This is a fantastic comedy that Ataru and his wife Lum, an invader from space, cause excitement involving their neighbors." - from a badly translated Urusei Yatsura poster) ttwang@polyslo.calpoly.edu
jima@hplsla.HP.COM (Jim Adcock) (10/07/89)
>//Thomas Wang >//I need to know the byte offset of 'header' in class 'foo' before any >//'foo' object is allocated. class foo { public: int grr; int header; //does header stuff really need to be public? void alloc(); }; void foo::alloc() { cout << (&(this->header)) - this << "\n"; // bomb! 2.0 complains that this // is of type foo*, while &(this->header) is of type int*. Maybe you can get // away with coercing them both to type char*, but not guaranteed to work with // all compilers } main() { ((foo*) 0) -> alloc(); // bomb? -- possible on a machine that // disallows dereferencing a null pointer }
haynes@wsl.dec.com (Charles Haynes) (10/08/89)
The (relatively gross) hack we used in the X Intrinsics is: #define XtOffset(type,field) ((unsigned int)&(((type)NULL)->field)) This has a different set of problems from your example, but works on most architectures/compilers. Some "C"'s provide an offset builtin that you could use. As for the problems with your example: > class foo > { > public: > int grr; > int header; //does header stuff really need to be public? > void alloc(); > }; > > void foo::alloc() > { > cout << (&(this->header)) - this << "\n"; // bomb! 2.0 complains > // that this is of type foo*, while &(this->header) is of type int*. > // Maybe you can get away with coercing them both to type char*, but > // not guaranteed to work with all compilers That's right! You are subtracting things of different type. *I* wouldn't expect it to work in general. This is where I'd use the XtOffset macro. > } > > main() > { > ((foo*) 0) -> alloc(); // bomb? -- possible on a machine that > // disallows dereferencing a null pointer This should be possible on ANY machine. You aren't actually dereferencing anything, you're just selecting a member function and passsing "this" to it. "alloc" had better be ready to get a NULL "this" though. > } Hope this is helpful. -- Charles
jima@hplsla.HP.COM (Jim Adcock) (10/10/89)
>This should be possible on ANY machine. You aren't actually dereferencing >anything, you're just selecting a member function and passsing "this" to >it. "alloc" had better be ready to get a NULL "this" though. Well, my 680x0 compiler does a "lea" "load effective address" based on what you pass "alloc" --which is not quite actually dereferencing the pointer. But I wonder if machines that trap on null pointers wouldn't actually trap on their equivalent to "lea" ???