Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!husc6!cmcl2!brl-adm!adm!bilbo.dobson@CS.UCLA.EDU From: bilbo.dobson@CS.UCLA.EDU (Peter Dobson) Newsgroups: comp.lang.c Subject: Re: Distinguished pointers (was Re: Weird syscall returns) Message-ID: <8383@brl-adm.ARPA> Date: Tue, 21-Jul-87 21:17:56 EDT Article-I.D.: brl-adm.8383 Posted: Tue Jul 21 21:17:56 1987 Date-Received: Thu, 23-Jul-87 06:43:17 EDT Sender: news@brl-adm.ARPA Lines: 53 > From: Rahul Dhesi> Newsgroups: comp.lang.c > Subject: Distinguished pointers (was Re: Weird syscall returns) > Date: 15 Jul 87 16:14:16 GMT > To: info-c@brl-smoke.arpa In article <846@bsu-cs.UUCP> dhesi@bsu-cs.uucp (Rahul Dhesi) writes: > On the contrary, I think we need more distinguished pointer values, not > just a single zero or NULL value. I have a set of custom I/O routines > that use the pointer value NOFILE to indicate that no file could be > opened (equivalent to (char *) 0 in current C implementations) and > another pointer value NULLFILE to indicate that the custom I/O library > routines should ignore all output to this file (equivalent to the value > (char *) -1 but conceptually equivalent to opening /dev/null for > output, except that a file descriptor isn't wasted and the existence of > a null device or its name need not be presumed). > Consider again how gets(3) indicates end-of-file and error. If there > were two distinguished pointer values, one could test for both > end-of-file and for error without using the botched-up errno. > Upward compatibility will prohibit doing this for gets(), but the need > for more than one distinguished pointer is clear. We already have a > (char *) -1; let's just give it a different name and keep it. Then > sbrk can return ERRPTR on error, and we can define ERRPTR as > (char *) -1, and remain fully compatible to boot. > -- > Rahul Dhesi UUCP: {ihnp4,seismo}!{iuvax,pur-ee}!bsu-cs!dhesi A portable way to do this is to declare a global data object that is just used as a location for a pointer to point to, like: /* outside a function declaration */ char nofile, nullfile; #define NULLFILE &nullfile #define NOFILE &nofile This way the pointers will be valid values on all machines, and won't contain a value that is valid in a pointer to point to any data object (as the characters nullfile, and nofile aren't used.) This may fail on machines where pointers can't be cast from type (char *) to another type and back again. For example in MicroSoft C on MS-DOS in some memory models a pointer to character cast to pointer to function, cast back to pointer to function, doesn't work. I don't think this is likely to be a problem on any implementations where all the pointer types point to data. --- Peter