Path: utzoo!attcan!uunet!cs.utexas.edu!rice!uw-beaver!cornell!peierls From: peierls@svax.cs.cornell.edu (Tim Peierls) Newsgroups: comp.lang.c++ Subject: Pointer conversion macro brainteaser Message-ID: <43645@cornell.UUCP> Date: 23 Jul 90 05:58:49 GMT Sender: nobody@cornell.UUCP Reply-To: peierls@cs.cornell.edu (Tim Peierls) Distribution: comp Organization: Cornell Univ. CS Dept, Ithaca NY Lines: 33 The overparenthesized and implementation dependent nightmare below "converts" a base pointer to a derived pointer, in defiance of the rules. If you don't see any use for such a trick or if you are appalled at the whole idea, then read no further. The question is, for all you spec hackers, under what conditions is this macro guaranteed by E&S to work? By "conditions" I mean nasty things like implementation defined behavior, and by "work" I mean conform to the description below in some useful if not rigorous way. #define bp2dp(B,D,p) ((p)?((D*)(((char*)(p))+1-((size_t)(B*)(D*)(void*)1))):0) Usage: B* bp; D* dp; dp = bp2dp(B,D,bp); Assuming that class D is (non-virtually) derived from class B, the macro takes a B* and returns a D*, such that (using the example names) "bp == (B*) dp", for all bp for which "(B*) dp" is defined (including 0). It works for cfront 2.0 and probably everywhere else. A reasonable translator or compiler should have no problem turning the entire expression into a compare and a subtract. For example, cfront turns ((B*)(D*)(void*)1) into a conditional expression with a constant condition that cc can turn into a constant expression. A related question: When does the offsetof(T,mem) macro work? (It's defined in my stddef.h.) Name : Tim Peierls Mail : peierls@svax.cs.cornell.edu Scotch : Laphroaig