A lint question

Guy Harris guy at auspex.UUCP
Wed Nov 30 03:50:28 AEST 1988


>function argument ( number ) used inconsistently
>    malloc( arg 1 )   	llib-lc(338) :: findlinks.c(114)
>    read( arg 3 )   	llib-lc(104) :: findlinks.c(127)
>
>I assume that lint is telling me that I am calling malloc() and
>read() with an inconsistent number or parameters.  How can I be
>inconsistent with the number of parameters with one call to
>malloc()?

Easy.  Note that the complaint lists file "llib-lc", line 338, and file
"findlinks.c", line 114.  I presume "findlinks.c", line 114, is

>directory = (char *)malloc((int)stbuf.st_size);

On my system, the relevant line in "llib-lc" is

	char *	malloc(n) unsigned n; {static char c; return(&c);}

Note the "unsigned n".  It's probably an "unsigned" on your machine as
well.

"function argument ... used inconsistently" means there are two places
that don't agree on the type of the function argument; one of those
places may be the *definition* of the function.  For system libraries,
the "definition" for the benefit of "lint" appears in a "lint library",
which is generally either located in "/usr/lib" or "/usr/lib/lint".

In your case, while there was only one *call* to "malloc", there was a
*definition* in either "/usr/lib/llib-lc" or "/usr/lib/lint/llib-lc",
and they did not agree.

In C implementations, "malloc" generally takes an "unsigned int" as its
argument, not an "int".  I think the current dpANS specifies this as
well.

As for the calls to "read":

>They look pretty consistent to me, especially in the argument
>count!

It is necessary, but not sufficient, that the argument count be the same
(in the case of functions whose definition is preceded with a
/*VARARGS*/-type comment, it isn't even necessary; this permits "lint"
to, for example, check that the first argument to "printf" is a "char *"
but not check the other arguments).  Let's look at the calls:

>if (read(fd, directory, (int)stbuf.st_size) != (int)stbuf.st_size) {
>	.
>	.
>	.
>while (read(fd, &mntbuf, sizeof(MNT)) == sizeof(MNT)) {
>	.
>	.
>	.
>}
>while (read(fd, nextentry, sizeof(nextentry)) == sizeof(nextentry)) {

The second argument to "read", under UNIX, is supposed to be a "char *".
"directory" is (as declared) a "char *"; however, "mntbuf" may not be a
"char", in which case "&mntbuf" may not be a "char *", and "nextentry"
may be neither a "char *" nor a "char []".  If you pass something other
than a "char *" to "read" as its second argument,

	1) Make sure you're not doing something wrong - for instance,
	   the following is wrong:

		int answer;

		(put terminal into character-at-a-time mode)
		(void) printf("Erase disk? (y or n) ");
		read(0, &answer, 1);
		if (answer == 'y')
			erase();

	   In this particular case, you want to read a single character;
	   this code will do so, but it won't necessarily put it where
	   you expect it to.  There's no guarantee that if the user
	   types a "y", the value left in "answer" after the "read" will
	   be a "y".

	2) Once you're sure you're doing the right thing, cast the
	   pointer in question to "char *":

		while (read(fd, (char *)&mntbuf, sizeof(MNT)) == sizeof(MNT)) {

The *third* argument to "read" is, in POSIX, an "unsigned int", as I
remember.  It may be an "int" in some current UNIX implementations. 
Again, check your documentation and your "/usr/lib/llib-lc" or
"/usr/lib/lint/llib-lc".

If it's an "int", the problem may be with the "sizeof"s.  In more recent
C compilers, the type of the result of "sizeof" is "unsigned int".  If
so, they should be cast to "int" (if, that is, the third argument to
"read" is supposed to be "int").

If it's an "unsigned int", the problem should be obvious....



More information about the Comp.lang.c mailing list