From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=BAYES_00,INVALID_DATE, MSGID_SHORT autolearn=no autolearn_force=no version=3.4.4 Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!rutgers!seismo!mimsy!chris From: chris@mimsy.UUCP Newsgroups: comp.lang.c,comp.lang.ada Subject: Re: How to get Ada private types in C Message-ID: <5767@mimsy.UUCP> Date: Thu, 12-Mar-87 03:22:06 EST Article-I.D.: mimsy.5767 Posted: Thu Mar 12 03:22:06 1987 Date-Received: Fri, 13-Mar-87 05:03:45 EST References: <172@m10ux.UUCP> <513@ci-dandelion.UUCP> Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 Xref: utgpu comp.lang.c:1236 comp.lang.ada:174 List-Id: While I do not know the precise details of Ada private types, I can say that in general, private types are in fact implemented through the use of a `generic pointer' type. That is, outside of a specific module, the only handle anything has on an object of a private type is a pointer to that object. In 4BSD, the generic pointer type is `caddr_t' (Core ADDRess Type); in ANSI draft C it is `void *' (a name that I find utterly lacking in taste, though it does avoid a new keyword). For example, a private data structure that implments longer integers might look like this: struct longer { long low; long high; }; but the routines that deal with one of these take and return only `caddr_t' types: caddr_t new_longer() { struct longer *l; l = (struct longer *) malloc(sizeof (struct longer)); if (l != NULL) l->low = l->high = 0; return ((caddr_t) l); } void incr(obj) caddr_t obj; { struct longer *l = (struct longer *) obj; if (++l->low == 0) /* overflow */ l->high+++; } This is often employed in an `object oriented' manner by providing a structure containing pointers to the object-specific routines, as well as an instance of the object itself: struct representation { caddr_t r_obj; /* the object */ void (*r_incr)(); /* a function that counts it up */ void (*r_print)(); /* a function that prints it */ }; In this case, only the routine that creates a specific instance of an object need know the names of the functions that implement that object. Everywhere else in the code, only the operations provided by the `representation' are available: add_1_and_print(r) register struct representation *r; { (*r->incr)(r->obj); (*r->print)(r->obj); } Of course, doing this is considerably simpler if the compiler helps out, which is why we have languages like C++ in the first place. Otherwise we could all write the C code that the C++ compiler produces. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu