Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!bloom-beacon!adam.pika.mit.edu!scs From: scs@adam.pika.mit.edu (Steve Summit) Newsgroups: comp.lang.c Subject: Re: %p and different pointer representations Message-ID: <9571@bloom-beacon.MIT.EDU> Date: 3 Mar 89 05:43:10 GMT References: <11915@haddock.ima.isc.com> <9765@smoke.BRL.MIL> Sender: daemon@bloom-beacon.MIT.EDU Reply-To: scs@adam.pika.mit.edu (Steve Summit) Lines: 55 In article <11915@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >Therefore, a completely generic pointer >type (to function or data) is `union {void (*)(void); void *}', though I can't >think of any practical use for such a thing. In article <9765@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) writes: >I don't understand why so many people seem to be concerned about >packing both object AND function pointers into the same type of >variable. (By the way, it CAN be done; use a union.) What sort >of program calls for such weirdness, anyway? The only genuine >"problem" I've seen mentioned is the inability to portably print >out a function pointer, something I don't think is all that useful. I will have to use a variation on this union in the symbol table and the rvalue structure of a C interpreter I wrote once, if I ever want it to pass ANSI muster. (I'm not sure I'll bother.) So far, the interpreter's symbol table has assumed that there is one type which can contain any pointer, to code or data. There is also an "nm" ("namelist") command, which prints the symbol table; this command has been using %p but will require revision if %p will not portably print a function pointer. The same difficulties would hold for any assemblers, linkers, or other object file manipulation programs (nm, etc.) written in C on a system with incompatible code and data pointers. Those programs don't have to be portable, and can use whatever system- dependent kludges are required. It's more troublesome for the interpreter, most of which (outside of its dynamic linker) is quite portable. Admittedly, a C interpreter is a rather extreme, one-of-a-kind program, that pushes the edges of the envelope in several ways. (The dynamic linker reads object code into malloc'ed memory and then jumps to it, a maneuver which some architectures reject outright. Others require a special call to create new text segments, which the interpreter would have to use.) Steve Summit scs@adam.pika.mit.edu P.S. The astute reader may wonder why an interpreter needs to handle code pointers at all, since the "code" being interpreted by an interpreter is really data. However, an interpreter that allows intermixing of interpreted and compiled code must keep "code" pointers, whether to interpreble or compiled code, as true code pointers, partly to keep function calls made from interpreted code consistent, and more importantly to allow calls from compiled code back to interpreted code to be made at all. (When you link and relocate object code with undefined external references, you've got to have a real function pointer to fill in. Arranging that calls to interpreted routines from compiled code work is a challenging problem, and is left as an exercise for the reader :-). A correct solution allows installing interpreted routines as signal handlers, a fascinating concept.)