[net.bugs.usg] "lint" lets very bad code pass

guy@sun.uucp (Guy Harris) (07/21/85)

The V7 "lint" (or, at least, the version of it that comes with 4.2BSD),
gives error messages for code that passes an "int" value to a routine that
expects a "long" or pointer value, even though such code is likely to work
on 4.2BSD systems which will have 32-bit "int"s.

However, the System V Release 2 "lint" had code added to it *specifically*
to prevent it from complaining about this on machines with sizeof(int) ==
sizeof(long) if the actual argument is a constant.  This is a bad idea for
several reasons:

	1) it means that you can't check for this kind of code - which
	   *will* fail on machines with 16-bit "ints" and 32-bit pointers,
	   and in the case of "int" actual parameters and "long" formal
	   parameters, will even fail if "int"s and pointers are the same
	   size - unless you run "lint" on the target machine

which further implies that

	2) if you're doing cross-development on a machine on which
	   sizeof(int) == sizeof(long) for a machine on which sizeof(int)
	   != sizeof(long), you have *no way* to "lint" your code unless
	   you either can run "lint" on the target machine (which may be
	   a small one-board dedicated system with *no* operating system)
	   or you keep a machine with sizeof(int) != sizeof(long) solely
	   for the purposes of doing cross-development.

I can sympathize - *very* slightly - with the people who get pages of
complaints from "lint" about

	mumble(NULL);	/* should be (struct frobozz *)NULL */

*ONLY* if this code wil *NEVER EVER* run on a machine other than the one
they're doing development on.  Some people may not run "lint" because it
insists they think more abstractly when coding than they'd like to, so
eliminating these diagnostics may induce them to run "lint".  However, the
correct solution to this problem is to get the ANSI C standard out the door
and get *everybody* to start declaring the return type and argument type to
*all* functions they use - you only have to declare it once and the compiler
will cast all 0s passed as arguments to the proper pointer type and all
"int" values (constant *or* variable) to "long" when necessary.  The correct
solution for the interim is to have managers require that their people
"lint" their code whether they want to or not.

For those of you who realize why the code that earlier "lint"s complained
about is bad, you can make the System V "lint" complain too by deleting the
two lines that read

		if( sizeof(int) == sizeof(long) && !pflag ) return( 0 );

from the routine "chktype" in "lpass2.c".  This line was *not* present in
earlier "lint"s, and is the culprit.  (One should *NOT* have to specify the
"-p" flag - which checks for portability to various non-UNIX implementations
of C - in order to get it to check for a bug which impairs portability to
perfectly good UNIX C implementations.)

	Guy Harris

jerry@oliveb.UUCP (Jerry Aguirre) (07/31/85)

> The V7 "lint" (or, at least, the version of it that comes with 4.2BSD),
> gives error messages for code that passes an "int" value to a routine that
> expects a "long" or pointer value, even though such code is likely to work
> on 4.2BSD systems which will have 32-bit "int"s.
> 
> However, the System V Release 2 "lint" had code added to it *specifically*
> to prevent it from complaining about this on machines with sizeof(int) ==
> sizeof(long) if the actual argument is a constant.  This is a bad idea for
> several reasons:
> 	Guy Harris

A test like this should be under control of the -p or -c option of lint.
Does it still allow int-long equality if you use the -p option?

				Jerry Aguirre @ Olivetti ATC
{hplabs|fortune|idi|ihnp4|tolerant|allegra|tymix}!oliveb!jerry

peter@kitty.UUCP (Peter DaSilva) (07/31/85)

> For those of you who realize why the code that earlier "lint"s complained
> about is bad, you can make the System V "lint" complain too by deleting the
> two lines that read
> 
> 		if( sizeof(int) == sizeof(long) && !pflag ) return( 0 );
> 
> from the routine "chktype" in "lpass2.c".  This line was *not* present in
> earlier "lint"s, and is the culprit.  (One should *NOT* have to specify the
> "-p" flag - which checks for portability to various non-UNIX implementations
> of C - in order to get it to check for a bug which impairs portability to
> perfectly good UNIX C implementations.)
> 
> 	Guy Harris

Portability is portability. This is the first time I've heard that lint only
checks for portability to non-UNIX systems. The documentation refers to the
GCOS & IBM dialects of 'C'. Since UNIX runs on IBM mainframes shouldn't it
complain about such things as "if(c<'0')", since this isn't portable to
certain UNIX systems?

guy@sun.uucp (Guy Harris) (08/02/85)

> > The V7 "lint" (or, at least, the version of it that comes with 4.2BSD),
> > gives error messages for code that passes an "int" value to a routine that
> > expects a "long" or pointer value, even though such code is likely to work
> > on 4.2BSD systems which will have 32-bit "int"s.
> > 
> > However, the System V Release 2 "lint" had code added to it *specifically*
> > to prevent it from complaining about this on machines with sizeof(int) ==
> > sizeof(long) if the actual argument is a constant.  This is a bad idea for
> > several reasons:
> > 	Guy Harris
> 
> A test like this should be under control of the -p or -c option of lint.
> Does it still allow int-long equality if you use the -p option?

1) "-c option"?  That option tells "lint" to compile a "lint" library.  Why
should that have anything to do with this?

2) It doesn't allow int-long equality with "-p"; unfortunately, "-p"
disallows a number of other things, and uses a different "lint" library.
"-p" means "check whether this will port to UNIX *or* GCOS *or* OS/360 C".
There needs to be a "check whether this will port to UNIX C with a
7-character identifier limit" and "check whether this will port to UNIX C
assuming no identifier length limit".  (There also needs to be a "check
whether this will port to ANSI C" once ANSI C becomes an official standard.)
I want to check whether code will port to any other UNIX implementation;
right now, I can't have that without the 6-character identifier limit and a
check against a different C library.

	Guy Harris

guy@sun.uucp (Guy Harris) (08/03/85)

> This is the first time I've heard that lint only checks for portability
> to non-UNIX systems.

Umm, well, actually it can either check:

	1) Whether the code is reasonably safe on the machine that "lint"
	   is running on - this also implies a check against the "standard"
	   C library instead of the "portable" C library.  On UNIX systems,
	   the "standard" C library includes all routines in sections 2
	   and 3 (well, it *should* include them - the 4.2BSD "lint"
	   library for the standard C library has many lacunae).  Also,
	   it assumes the "native" rules for identifier length.

	2) Whether the code is reasonably safe on any of the C
	   implementations it knows about - this includes UNIX,
	   GCOS, and, I believe, OS/360 and successors.  This implies
	   
	   a) assuming a set of data type lengths which are basically
	      those of a machine with 16-bit "int"s and pointers.

	   b) checking against a "portable" subset of the C library.
	   
	   c) a 6-character limitation on identifier length.

> Since UNIX runs on IBM mainframes shouldn't it complain about such things
> as "if(c<'0')", since this isn't portable to certain UNIX systems?

How so?  I believe the 370-and-clones UNIX implementations use ASCII - at
least some of them do.  Even if they used EBCDIC, I believe they use
unsigned "char"s, so the fact that some EBCDIC characters have the eighth
bit on shouldn't matter.   (Heck, the 3Bs have unsigned "char"s, and that
particular test is OK there.)

	Guy Harris

jerry@oliveb.UUCP (Jerry Aguirre) (08/06/85)

> 1) "-c option"?  That option tells "lint" to compile a "lint" library.  Why
> should that have anything to do with this?
>
> 	Guy Harris

We must have very different versions of lint.  Here is an extract from the
4.1BSD lint man page listing of options:

     a    Report assignments of long values to int variables.

     c    Complain about casts which have questionable portabil-
          ity.

This seems to match what the code says those options do.

				Jerry Aguirre @ Olivetti ATC
{hplabs|fortune|idi|ihnp4|tolerant|allegra|tymix}!oliveb!jerry

guy@sun.uucp (Guy Harris) (08/08/85)

> > 1) "-c option"?  That option tells "lint" to compile a "lint" library.
> > Why should that have anything to do with this?

> We must have very different versions of lint.  Here is an extract from the
> 4.1BSD lint man page listing of options:
>
>      c    Complain about casts which have questionable portabil-
>           ity.

Yes, we certainly do have different versions of "lint".  Here is an extract
from the System V Release 2 lint man page listing of options:

     -c     Cause *lint* to produce a ".ln" file for every ".c" file
            on the command line.

Note: 1) this discussion was about System V Release 2 "lint" and 2) this
newsgroup is "net.bugs.usg" which, presumably, is intended for bug reports
about "USG" (now USDL) UNIX systems, like S3 and S5, or for bug reports
which apply equally well to USDL systems and other systems, not for bug
reports which apply only to V7, 2.xBSD, or 4.xBSD systems.

	Guy Harris

jim@ISM780B.UUCP (08/11/85)

>> > 1) "-c option"?  That option tells "lint" to compile a "lint" library.
>> > Why should that have anything to do with this?
>
>> We must have very different versions of lint.  Here is an extract from the
>> 4.1BSD lint man page listing of options:
>>
>>      c    Complain about casts which have questionable portabil-
>>           ity.
>
>Yes, we certainly do have different versions of "lint".  Here is an extract
>from the System V Release 2 lint man page listing of options:
>
>     -c     Cause *lint* to produce a ".ln" file for every ".c" file
>            on the command line.

In V7, -c meant "suppress complaints about questionable casts".
In SysIII, -c meant "complain about questionable casts".
SysV lint had no -c.
In SysV.2, lint -c is to *.ln as cc -c is to *.o .

Sigh.

-- Jim Balter, INTERACTIVE Systems (ima!jim)