Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!crdgw1!jupiter!larocque From: larocque@jupiter.crd.ge.com (David M. LaRocque) Newsgroups: comp.lang.c Subject: Re: Pointing pointers at varying types of objects.(solution) Summary: solution Message-ID: <7328@crdgw1.crd.ge.com> Date: 2 May 90 22:00:08 GMT References: <7301@crdgw1.crd.ge.com> Sender: news@crdgw1.crd.ge.com Lines: 83 In article <7301@crdgw1.crd.ge.com>, larocque@jupiter.crd.ge.com (David M. LaRocque) writes: > > I am currently involved in translating a large Lisp > program into C. Much of the code has already been > translated by another person and something they did > has me concerned. Since in Lisp variables are not > typed, any variable can have any Lisp object as its > value. To deal with this problem my predecessor > wrote code that would perform operations on "generic" > data. I posted this message earlier today and have gotten the solution I had hoped for. Many thanks to Chris Torek (chris@cs.umd.edu) and for his solution which I am including (without his permission, but I don't think he'll mind). ****** Chris' solution start ********************** If you limit yourself to data pointers, you can use `char *' (old C) or `void *' (ANSI C) as a `generic' pointer type. The resulting pointers will always point to `char's or to mystery-objects and must always be cast to something else before you can use them; this will convert word pointers or typed pointers on machines that have such. For instance: struct tree { struct tree *left; struct tree *right; void *object; }; void *search(struct tree *top, void *obj, int (*compar)()) { int x; while (top != NULL) { x = (*compar)(top->object, obj); if (x == 0) /* we found it */ return top->object; if (x < 0) /* top->object < obj: move right */ top = top->right; else /* top->object > obj: move left */ top = top->left; } return NULL; /* obj not in tree */ } then: struct myobj { int mainval; int subval; char comment[24]; }; int mycompare(void *a1, void *a2) { struct myobj *o1 = a1, *o2 = a2; if (o1->mainval < o2->mainval) return -1; if (o1->mainval > o2->mainval) return 1; if (o1->subval < o2->subval) return -1; if (o1->subvaxl > o2->subval) return 1; return 0; /* equal */ } ... struct myobj *p; if ((p = search(objtree, (void *)&temp, mycompare)) == NULL) ... not in tree ... else printf("%.*s\n", sizeof(p->comment), p->comment); This is not quite as convenient as in Lisp. Chris ************* End Chris' solution **************** /************************************************** * larocque@crd.ge.com (518) 387-5805 * ...!crdgw1!cetus.crd.ge.com!larocque **************************************************/