questions from using lint

KW Heuer kwh at bentley.UUCP
Fri May 9 12:54:50 AEST 1986


In article <501 at brl-smoke.ARPA> rbj at 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



More information about the Comp.lang.c mailing list