les@chinet.chi.il.us (Leslie Mikesell) (07/18/89)
In article <10541@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >-#define NO_FOOBAR ((struct foobar *) -1 ) is what I use, but... >This is not portable. Just use NULL. Do you mean that there are machines that might return a valid -1 from sbrk(2) or shmat(2), or that would misconstrue the comparsion of a pointer to -1? Yes, I know these are botches, but are they not always accomodated? Les Mikesell
chris@mimsy.UUCP (Chris Torek) (07/18/89)
(This is more a `unix' question than a `C' question; I have cross-posted this and redirected followups back to comp.lang.c.) >In article <10541@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >>... Just use NULL. In article <8990@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: >Do you mean that there are machines that might return a valid -1 from >sbrk(2) or shmat(2), or that would misconstrue the comparsion of >a pointer to -1? Yes, I know these are botches, but are they not >always accomodated? There are no existing machine/compiler combinations now running System V that cannot handle this, as far as I know. It is likely that in at least one case this was acheived by slowing down everything else for the sake of making the botches work. It is worth noting (particularly in comp.unix.questions/INFO-UNIX, but only once) that in C the integer constant `0' is *also* the untyped nil pointer. All other integer constant values are simply integer constant values; zero is a special case. Somewhere inside the guts of every C compiler is some code that, in appropriate contexts, converts `integer constant zero' to `nil pointer to T' for some type T. Even on VAXen, the special-case code must be there to decide whether to complain about pointer/integer conversion. This same special case code is free to alter the value and/or number of bits in the resulting nil pointer to T, and on some machines it does. There are only two ways that the untyped nil pointer can acquire a type, namely assignment and comparison. Casts are a special case of assignment, as are arguments to functions that have prototypes in scope (`ANSI C'). Where this causes the most trouble is in arguments to functions that do not have prototypes in scope, or for which the prototype does not specify a type for that argument: e.g., execl(): f() { void execl(char *, ...); execl("prog", "prog", "arg1", "arg2", ___); } Languages like Pascal use the keyword `nil' for their untyped nil pointers. This has the advantage that it does not have any other meaning, and the compiler can complain if it sees something like execl("prog", "prog", "arg1", "arg2", nil); where the information needed to convert `nil' to `nil pointer to char' is missing. C compilers must simply assume that the fifth argument is already correct, no matter what is written there---if you write `0' without a cast, they will figure you meant the integer value zero. It is also worth noting that while the integer value zero is made up of a string of zero bits, a nil pointer (of any arbitrary type T) need not be so. The folks at the S-1 project (in LLL) tried to build such a machine and put a Unix-derived system on it, but ran into so much trouble from code that did not cast its `0' constants to nils that they modified the hardware to allow it instead. There are machines made today in which the format of pointers to words and pointers to bytes differ (e.g., Data General). This causes similar grief to careless programmers, because conversions between (char *) and (int *) (e.g.) are no longer no-ops (they compile into shift-and-mask operations). Both of these problems will never plague you if you are careful to distinguish between integers and pointers, and between pointers to one type and pointers to another. -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@smoke.BRL.MIL (Doug Gwyn) (07/19/89)
In article <8990@chinet.chi.il.us> les@chinet.chi.il.us (Leslie Mikesell) writes: -In article <10541@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: ->>#define NO_FOOBAR ((struct foobar *) -1 ) is what I use, but... ->This is not portable. Just use NULL. -Do you mean that there are machines that might return a valid -1 from -sbrk(2) or shmat(2), or that would misconstrue the comparsion of -a pointer to -1? What I mean is what I said. -Yes, I know these are botches, but are they not always accomodated? No. Non-UNIX systems need not even try to accommodate them.