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);
}