I'm working up a set of pointer<->offset typesaftey wrappers, for eventual use in apr_shmem allocations [which cannot store pointers] and a new companion interface, apr_rmm (for relocatable memory management) which will implement the alloc/free stuff for any block of memory, including shmem. [apr_shmem will simply manage a single, big allocation, and let the apr_rmm_ handle applications such as the auth_digest store.]
The code below works, rather nicely. But I have a big issue that I can't express the APR_SET_ADDR and APR_SET_OFFSET in a manner than makes them a legitimate lhs or rhs expression without loosing typesaftey. If anyone has any useful observations, I'd really appreciate it :) Bill #define APR_DECLARE_OFFSET_TYPE(roottype) \ typedef struct { \ roottype * p_oof; \ } roottype##_off_t #define APR_OFFSET(roottype) \ roottype##_off_t #define APR_SET_OFFSET(target, object, base) \ (target).p_oof = (void*)(((char*)(object) - (char*)(base)) \ + ((object) - (target).p_oof) \ - ((object) - (target).p_oof)) #define APR_SET_ADDR(target, off, base) \ (target) = (void*)(((char*)(base) + (int)((off).p_oof)) \ + ((target) - (off).p_oof) \ - ((target) - (off).p_oof)) typedef struct mytype1 mytype1; APR_DECLARE_OFFSET_TYPE(mytype1); typedef struct mytype2 mytype2; APR_DECLARE_OFFSET_TYPE(mytype2); typedef struct mytype1 { int n; APR_OFFSET(mytype2) first; } mytype1; typedef struct mytype2 { char c; APR_OFFSET(mytype2) next; } mytype2; int main() { mytype1 head; mytype2 node1; mytype2 node2; mytype1 *test1; mytype2 *test2; APR_OFFSET(mytype1) bitch; int stackpoint; /* This emits an error, as expected; */ APR_SET_OFFSET(bitch, &node1, &stackpoint); APR_SET_OFFSET(node1.next, &node2, &stackpoint); APR_SET_ADDR(test1, node1.next, &stackpoint); /* Must emit an error */ APR_SET_ADDR(test2, node1.next, &stackpoint); if (test1 == (void*)&node2) printf("test1 matched\n"); if (test2 == (void*)&node2) printf("test2 matched, outch!\n"); printf ("node is size %d, node1.next.p is %d", sizeof(node2.next), node1.next.p_oof); }