[comp.lang.misc] Yet Another Lint Foul-up

vevea@paideia.uchicago.edu (Jack L. Vevea) (01/06/89)

	I've passively watched the discussion of lint's problems with
  exit(0) from main(), and find myself wondering why it matters.  I use
  lint to check my code, but I've gotten into the habit of automatically
  ignoring certain output, including 'warning:  main() returns a random
  value to the invocation environment.'  Being primarily a psychometrician,
  and not a professional C (or any other language) programmer, I find myself
  wondering if some of you out there are working under conditions in which
  some higher authority requires you to produce a clean lint run as 
  evidence of good coding.  Otherwise, it would seem to me that any
  concern with the message would be evidence of your being a slave to
  lint; why else be concerned when you _know_ that the warning is
  inconsequential?

duane@cg-atla.UUCP (Andrew Duane) (01/06/89)

In article <1298@tank.uchicago.edu>, vevea@paideia.uchicago.edu (Jack L. Vevea) writes:
> 
> 	I've passively watched the discussion of lint's problems with
>   exit(0) from main(), and find myself wondering why it matters.  I use
>   lint to check my code, but I've gotten into the habit of automatically
>   ignoring certain output, including 'warning:  main() returns a random
>   value to the invocation environment.'  Being primarily a psychometrician,
>   and not a professional C (or any other language) programmer, I find myself
>   wondering if some of you out there are working under conditions in which
>   some higher authority requires you to produce a clean lint run as 
>   evidence of good coding.  Otherwise, it would seem to me that any
>   concern with the message would be evidence of your being a slave to
>   lint; why else be concerned when you _know_ that the warning is
>   inconsequential?

But sometimes the exit value of a program is important. I
regularly use many shell scripts that require correct (and
explicit) exit codes. Also, the system() library routine
returns (in a contorted fashion) the exit code of the program;
thus other programs can depend on it. GREP is a good example of
this.

If "main() returns a random value to the invocation environment"
then these scripts may break unpredictably; worse, they may
WORK unpredictably. And you never know when some little helper
program may be used in such a script. Big programs are not
immune, either. Someday, someone may want to wrap up that huge
database program in a little helper script for novices, and
need that exit value.

Andrew L. Duane (JOT-7)  w:(508)-658-5600 X5993  h:(603)-434-7934
Compugraphic Corp.			 decvax!cg-atla!duane
200 Ballardvale St.		       ulowell/ \laidback
Wilmington, Mass. 01887		   cbosgd!ima/   \cgeuro
Mail Stop 200II-3-5S		     ism780c/     \wizvax

Only my cat shares my opinions, and she hasn't returned to the
invocation environment yet.

jas@ernie.Berkeley.EDU (Jim Shankland) (01/07/89)

In article <1298@tank.uchicago.edu> vevea@paideia.UUCP (Jack L. Vevea) asks
(paraphrased), why people make a fuss about lint messages that they
know to be inconsequential -- is it that a higher authority requires
that their code be lint-free, or are they just being obsessive "slaves
to lint?"

Sometimes, a higher authority does require lint-free code.  This is not
a bad thing, even if you do have to do some pretty strange things
(e.g., using "#ifdef lint") to make it happen.  Even when there is no
such higher authority, it's a good idea to arrange for code to be
completely lint-free.  While I *know* that "possible pointer alignment
problem" on return from malloc() is inconsequential, other, even
more highly paid software engineers :-) "know" that all kinds of other
lint messages are inconsequential, because the code works fine on their
VAX.  This is a sad fact; very sad, but very much a fact.

Second, if my code generates n inconsequential lint messages, then every
time I re-lint the code, I have to pick out the "real" lint, if any,
from the n inconsequential messages.  This is burdensome and error-prone.
Better to habitually use a few contrivances that eliminate the harmless
lint messages.

(Of course, the above-mentioned software engineers may then put all sorts
of unsafe weirdness into their code "to shut lint up".  Ultimately,
this is a major problem with C:  it's too easy to write non-portable code,
and too hard to specify the rules for writing portable code.  No, I'm
not proposing a solution, and I'm certainly not saying we should all
be programming in Pascal -- just pointing out a *very* costly problem
with the language.  If you doubt me, consider this small example:
what percentage of C programmers do you think know what the correct
definition of NULL is, and when NULL needs to be preceded by a type cast,
despite regular clarifications of the question in comp.lang.c?  No
fair counting those who "know" an answer that is wrong!)

Jim Shankland
jas@ernie.berkeley.edu

guy@auspex.UUCP (Guy Harris) (01/07/89)

>	I've passively watched the discussion of lint's problems with
>  exit(0) from main(), and find myself wondering why it matters.  I use
>  lint to check my code, but I've gotten into the habit of automatically
>  ignoring certain output, including 'warning:  main() returns a random
>  value to the invocation environment.'

Sometimes messages like this may *not* be inconsequential; it's probably
better to tweak your code to eliminate as many such messages as
possible, rather than to ignore them.

>  Being primarily a psychometrician, and not a professional C (or
>  any other language) programmer, I find myself wondering if some
>  of you out there are working under conditions in which some higher
>  authority requires you to produce a clean lint run as evidence
>  of good coding.

At Sun, the kernel is expected to pass "lint"; the "-h", "-b", "-x", and
"-n" flags are used, and the only messages removed (with "grep -v") are

	struct/union <XXX> never defined

and

	possible pointer alignment problem

Many times I have been *V*E*R*Y* grateful that "lint" caught coding
errors in my, and other people's, code before I tested a kernel.

>  Otherwise, it would seem to me that any concern with the message
>  would be evidence of your being a slave to lint; why else be
>  concerned when you _know_ that the warning is inconsequential?

Because, as noted, the message may *not* be inconsequential; a program
that

	1) falls off the end of "main"

and

	2) is used in a context where exit statuses are checked

may screw up.  Consider some program used in a Makefile, for instance;
if it randomly returns a non-zero exit status, and you haven't told
"make" to keep going if that command fails, your Makefile will fail. 
Yes, this really happens.

Since it's quite easy to make the complaint go away (e.g. by sticking
/*NOTREACHED*/ after the call to "exit"), it's better to do so than to
filter the complaints out.

bill@twwells.uucp (T. William Wells) (01/08/89)

In article <1298@tank.uchicago.edu> vevea@paideia.UUCP (Jack L. Vevea) writes:
:       I've passively watched the discussion of lint's problems with
:   exit(0) from main(), and find myself wondering why it matters.  I use
:   lint to check my code, but I've gotten into the habit of automatically
:   ignoring certain output, including 'warning:  main() returns a random
:   value to the invocation environment.'  Being primarily a psychometrician,
:   and not a professional C (or any other language) programmer, I find myself
:   wondering if some of you out there are working under conditions in which
:   some higher authority requires you to produce a clean lint run as
:   evidence of good coding.  Otherwise, it would seem to me that any
:   concern with the message would be evidence of your being a slave to
:   lint; why else be concerned when you _know_ that the warning is
:   inconsequential?

Here are the two reasons why one deals with this:

    1) Having put an exit() in the program, you should add
       /*NOTREACHED*/ right after it; this tells lint that you know
       what you are doing.

    2) If you do 1), as you should, getting the lint message means you
       screwed up: you didn't put an exit() or return where it
       belongs.

In short, if you are in the habit of ignoring this particular message,
you should change your habit. Always do 1) and, should you get the
message, investigate and fix the problem.

---
Bill
{ uunet!proxftl | novavax } !twwells!bill

miller@lll-crg.llnl.gov (Patrick Miller) (01/10/89)

With regards the ``exit'' (as well as any other routine that does
not exit).  Why not just include a line like

#define Exit(x)		exit(x) /*NOTREACHED*/

				Pat Miller
Patrick J. Miller		miller@lll-crg.llnl.gov
uucp:				{gatech,pyramid,rutgers}!lll-crg!miller
other things to try:		miller%lll-crg.llnl.gov@relay.cs.net

djones@megatest.UUCP (Dave Jones) (01/10/89)

From article <16441@lll-winken.LLNL.GOV>, by miller@lll-crg.llnl.gov (Patrick Miller):
> With regards the ``exit'' (as well as any other routine that does
> not exit).  Why not just include a line like
> 
> #define Exit(x)		exit(x) /*NOTREACHED*/
> 

Because cpp will probably remove the NOTREACHED comment.

The Sun3 version has a cpp flag which says, "Leave the comments in,"
but I don't think you can count on that being portable.

I'm kind of new to "lint".  Some of my programs from a
few years ago make lint go berserk. But now I lint my programs carefully,
as much for the benefit of generations to come as for my own purposes.
But it seems that some messages you just can't fend off without doing
all sorts of silly stuff.

I haven't been following the discussion, so perhaps this has been
suggested.  What you can do is to prepare an AWK script
to filter the output of lint.  Each tolerable message has an AWK-match
that throws it away.  The default AWK-match is to print the line.
When it's not obvious why you don't want the message, put a comment next
to the patern which matches it.

(P.S. I use new AWK, or "nawk" as it's called in 4.2 climes. It is a
distinct improvement over old AWK.  It is described in the new AWK
book by the original A, W, and K.: _The_AWK_Programming_Language_.)

tj@Alliant.COM (Tom Jaskiewicz) (01/11/89)

From article <16441@lll-winken.LLNL.GOV>, by miller@lll-crg.llnl.gov (Patrick Miller):
> With regards the ``exit'' (as well as any other routine that does
> not exit).  Why not just include a line like
> 
> #define Exit(x)		exit(x) /*NOTREACHED*/

	(really nice idea!)

In article <1163@goofy.megatest.UUCP> djones@megatest.UUCP (Dave Jones) writes:
>Because cpp will probably remove the NOTREACHED comment.

	Actually it doesn't, because:

>The Sun3 version has a cpp flag which says, "Leave the comments in,"
>but I don't think you can count on that being portable.

This flag exists specifically for use by lint.