Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site rlgvax.UUCP Path: utzoo!watmath!clyde!cbosgd!ihnp4!mhuxn!mhuxb!mhuxr!ulysses!allegra!mit-eddie!godot!harvard!seismo!rlgvax!guy From: guy@rlgvax.UUCP (Guy Harris) Newsgroups: net.lang.c Subject: Re: lint, pointers, 0 (what else?) Message-ID: <425@rlgvax.UUCP> Date: Wed, 6-Feb-85 13:27:24 EST Article-I.D.: rlgvax.425 Posted: Wed Feb 6 13:27:24 1985 Date-Received: Fri, 8-Feb-85 01:25:00 EST References: <366@harvard.ARPA> <8077@brl-tgr.ARPA> Distribution: net Organization: CCI Office Systems Group, Reston, VA Lines: 56 > (void) is an operation. Performing it when it is called for > should be no problem; apart from printf()/putc()/strcpy(), > one usually SHOULD test the return value of most functions. Even in the first two cases, it can be useful to test the return value, so that you can tell when a write fails (and let the poor user know that they've run out of space, or tried writing to a bad block, before the "fclose"; the reason 4.xBSD blasts the "out of space" messages to the user's terminal is probably that so few UNIX programs bother to check for the success of "write"s). "putc" is a nuisance, because you don't want to check on every "putc", just on those that actually write to the disk. I've cooked up "ifgetc" and "ifputc" macros that make this possible (the syntax is a bit ugly, but that's life). Unfortunately, they're based on the "getc" and "putc" macros from "stdio.h", and as such are protected by the terms of the UNIX license (and won't work on different implementations of the Standard I/O library anyway), but the trick is to do something like if (there's room(for putc)/data(for getc) in the buffer) put it there/get it from there; else if (flush(for putc)/fill(for getc)) fails and write code like for (;;) { c = generate_character(); ifputc(c, stdout) { perror("writing to stdout"); done(1); } } Also, another point on type-correctness: even on a Motorola 68000 implementation with 32-bit "int"s, you can lose if you don't declare functions which return pointers. See the article in the Dallas USENIX proceedings by the people from Motorola on the System V microport. The AT&T compiler (and, I'm told, the Sun compiler), put the return value of pointer-valued functions in A0 - NOT in D0. As such, if you don't declare "malloc" as returning "char *", its caller will expect the return value to be in D0 and will get whatever junk was there last. This is NOT (1000 times NOT) a valid reason to putting the return value in D0. It IS a valid reason for running your code through "lint". C implementations should not be governed by the problems of existing nonportable code; "lint" (as many of us are getting tired of saying) can be used to catch those quite nicely. Lots of us have no trouble using "lint". Lots of us have no trouble declaring functions and putting casts in front of NULL, or in front of functions whose return value we're ignoring. It's a pain to use your turn signal before turning - as evidenced by the number of people who don't do it - but it's worth doing. Trust me, it's worth doing. The same applies for trying to write type-correct code. Guy Harris {seismo,ihnp4,allegra}!rlgvax!guy