Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!think!harvard!seismo!brl-adm!brl-smoke!smoke!rbj@icst-cmr From: rbj@icst-cmr (Root Boy Jim) Newsgroups: net.lang.c Subject: Re: questions from using lint Message-ID: <820@brl-smoke.ARPA> Date: Tue, 13-May-86 20:11:20 EDT Article-I.D.: brl-smok.820 Posted: Tue May 13 20:11:20 1986 Date-Received: Sun, 25-May-86 06:38:58 EDT Sender: news@brl-smoke.ARPA Lines: 169 > 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.) Well C certainly makes the spelling less verbose, but that is not my complaint. The first structured language I came across (SIMPL-T at U of Md) used the notation `IF THEN { ELSE } END'. This has become my personal favorite paradigm for if statements. In fact, the syntax of all control statements was almost entirely similar to that used by the Bourne shell, except that END ended any kind of block. This is superior to the `one statement' (braces, BEGIN-END, etc) style because it explicitly delimits where the else statement goes. It is also easier to parse. > 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.) This is too scary, even for a scofflaw like myself. I don't trust white space, and you give up the ability to `cb' or `indent' it. > >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. I often do myself. EMACS C-mode adds them for you automatically, so I guess it's not much of an issue for some people. > >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? Oops, I goofed royally. BTW, I didn't notice that I needed the extra parens in the first example until I posted it. Another example of why not to use tricks. Silly rabbit :-) > >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 hadn't even thought of that. In my defense I will have to mention that 1) the expression may have already been computed in R0 anyway, 2) `tis a small matter, & 3) the attempt is to optimize cranial time rather than execution time. The statements of the left side are starting to get verbose, while the ones on the right side, especially if written on one lline, are simple and to he point. It might take you a bit to get used to the convention, but it's not that difficult. As for void, it didn't exist on the compiler I first used. Even BSD has problems with pointers to functions returning voids (did I get it right?) so I avoid them. It is easier just to default it to int, never return anything (or use my convention), and ignore the value. That's right, easier, not better. I'm lazy. Generally, tho, I find that I don't make *that* kind of mistake too often, so why bother? It all comes down to what you gain versus what you put out, and have to read for all eternity. > >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". Not true. The first case is required to be supported so that I can ignore a value (strcpy, eg) if I choose. The second is required to support printf. > >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 see your point. I first ran lint after I had a few thousand lines of code written, and it barfed unmercifully. Before that, I had attempted to run it but the permission bits were set wrong for some files. Only root could run it. By the time I figured out why, I had a bad taste in my mouth. Also, reading the documentation left me unexcited. Maybe I will give it another try someday. I'll probably point it at net.sources. I find I can get along okay without it. That is my whole point. It's not lint that bothers me, it's the people that think it's a panacea for everything. Actually, I am pleased by the mixed reaction I received. About half of the articles I've seen make this point as well. I do prefer the way it fits into the language tho. It's there when you need it but not shoved down your throat by run-time or compile-time checks. > >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. I meant to say `fclose', which can write data and thus barf too. > [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.) Mostly. But sometimes you don't care if the file you are trying to unlink or the descriptor you are trying to close doesn't exist. > 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" :-) Right. Grep -v helps here too. > >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. The explicitness comes in the source code. Why do you find it so hard to believe that I meant what I said? > Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint (Root Boy) Jim Cottrell The Sitting Lint Maker