Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!linus!philabs!cmcl2!harvard!topaz!bentley!kwh From: kwh@bentley.UUCP (KW Heuer) Newsgroups: net.lang.c Subject: Re: questions from using lint Message-ID: <797@bentley.UUCP> Date: Thu, 8-May-86 22:54:50 EDT Article-I.D.: bentley.797 Posted: Thu May 8 22:54:50 1986 Date-Received: Sun, 11-May-86 01:02:31 EDT References: <501@brl-smoke.ARPA> Organization: AT&T Bell Laboratories, Liberty Corner Lines: 100 In article <501@brl-smoke.ARPA> rbj@icst-cmr (Root Boy Jim) writes: >I have ranted about C using a one statement model for its control >statements instead of an explicit end statement. Compound statements are >bounded by braces instead. Yuk! Ah yes, there are two major types of language in the structured family; f77 with "endif" (some members use "end" for all of "endif", "endwhile", etc.) and pascal with "begin" "end" (which C abbreviates to "{" "}"). I presume this is what you dislike. (If it's the spelling that bothers you, I'm sure you're aware that you can define "begin" and "end" as macros.) Yet another convention, not endorsed by any language I know, is to dispense with the braces and let the indentation alone tell the compiler how to interpret the program. (I came up with this idea after an argument on the "correct" place to put the braces.) >Fortunately, there is the comma operator. This allows the following: > Most People Your's Truly > if (c) { if (c) > w = y; w = x, > y = z; y = z; > } /* look ma, no brace */ I can hardly flame you for this, since I've used it myself when in a hurry. (But I write it on one line, "if (c) w=x, y=z"). I usually end up rewriting it with braces, though. >Other things you will see in my code are: > exit((printf("usage: foo bar\n"),1)); >or even: exit(1,printf("usage: foo bar\n")); What's wrong with printf("usage: foo bar\n"), exit(1); as above? >Sufficeth to say that I use a lot of commas in my code. Unfortunately, >I cannot do this if either statement is a control struxure, *except* return. > Most People Your's Truly > if (c) { if (c) > w = y; return w = x, > return; > } /* look ma, no brace */ You're introducing a minor inefficiency, since the compiler will have to copy the result of the last expression into the return register. I presume you don't bother to declare void functions "void", either, or this wouldn't make it past the compiler. >I cannot see *any* implementation doing either of the following: > 1) barfing because I returned an *extra* value sometimes > 2) barfing because I added an extra argument You're probably correct in that all implementations that accept your code will produce correct results; however, I can easily imagine a compiler that would refuse to compile such an "obvious bug". >Now you may claim that this is `bad programming practice', but I claim >that it is just a convention, just like #defines are usually capitalized. >You may not like either one, but I claim this is portable. And, it is >meaningful to me. But it *is* bad practice, in a measurable sense: you are using a style which is indistinguishable from a bug. As a result, you cannot easily use lint to find *real* bugs, because you've introduced so much noise in the lint output. You're throwing away a useful tool unnecessarily. >I find it terribly ugly having to cast printf's or close's to void. Me too. But let's not lump all the cases together: [0] strcpy() returns a value that can be safely ignored. (Although I often find that I can use it in the next statement anyway.) [1] printf() returns a number which is normally pretty useless. It does also have an error return, but if you're writing to the terminal it's pretty safe to ignore that too. (Especially fprintf(stderr). What can you do if it fails, print an error message?) [2] close(), as near as I can tell, can only fail by being handed a number that does not denote an open file. I usually assume that this error would have been caught earlier. [3] unlink() and most other system calls should be checked! (It's too bad lint can't tell whether you've tested the return value of open(), etc.) My "solution" for [0]-[2] is simply to check the bottom of the lint output for "result ignored" messages, and decide which ones are serious. ("lint returns an error which is always ignored" :-) >And as someone pointed out, assignments return a value too, so should we >cast them to void as well? Oh yeah, assignment is `different'. Actually, this does bother me somewhat. I think I prefer the idea that values should be used or explicitly discarded, as in forth. (Not that forth has any error checking!) No, I'm not suggesting that lint should complain about assignments, or that C should have a different notation for assignments that are being pipelined into another expression. Just waiting for the next generation of languages. Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint