logan@vsedev.VSE.COM (James Logan III) (11/28/88)
I am having a problem with lint that I'm sure you have all seen before. I have 3 calls to the read() function and one call to malloc() which are all used in the same way (same number and type of arguments), yet lint has this complaint: 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()? The calls look like this: extern char *malloc(); char *directory; directory = (char *)malloc((int)stbuf.st_size); 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)) { . . . } They look pretty consistent to me, especially in the argument count! Any help would be appreciated. Thanks in advance. -Jim -- Jim Logan logan@vsedev.vse.com (703) 892-0002 uucp: ..!uunet!vsedev!logan inet: logan%vsedev.vse.com@uunet.uu.net
dhesi@bsu-cs.UUCP (Rahul Dhesi) (11/29/88)
In article <1256@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes: >function argument ( number ) used inconsistently > malloc( arg 1 ) llib-lc(338) :: findlinks.c(114) > read( arg 3 ) llib-lc(104) :: findlinks.c(127) Perhaps your lint library declares the argument to malloc, and the third argument to read, as unsigned, while you declare them as int. (Sigh.) You can't always make the same code lint properly under both SVR2 and 4.3BSD because of this. Damned if I do, unsigned if I don't. -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi
edf@rocky2.rockefeller.edu (David MacKenzie) (11/29/88)
In article <1256@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes: >I am having a problem with lint that I'm sure you have all seen >before. I have 3 calls to the read() function and one call to >malloc() which are all used in the same way (same number and type >of arguments), yet lint has this complaint: > >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 Actually, the "( number )" is just the column heading for the "arg n" fields. It means that argument number 1 was used inconsistently in with how it was defined in the lint library for malloc, and argument number 3 was used inconsistently in read. If you had called it with an inconsistent number of parameters, that comes under a different heading in the lint output, "function called with variable number of arguments". ----- David MacKenzie Environmental Defense Fund edf@rocky2.rockefeller.edu (...rutgers!cmcl2!rocky2!edf)
ok@quintus.uucp (Richard A. O'Keefe) (11/29/88)
In article <1256@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes: >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. Nope. Read that as "either a function argument has the wrong type, or the function has the wrong number of arguments". >extern char *malloc(); >char *directory; >directory = (char *)malloc((int)stbuf.st_size); ^^^^^^^^^^^^^^^^^ extern char *malloc(size_t howmuch); size_t is an unsigned integral type (except in BSD systems, where it's "int"). >if (read(fd, directory, (int)stbuf.st_size) != (int)stbuf.st_size) { ^^^^^^^^^^^^^^^^^^ extern int read(int fd, char *buffer, size_t howmuch); >while (read(fd, &mntbuf, sizeof(MNT)) == sizeof(MNT)) { ^^^^^^^ &mntbuf cannot be of type char* unless mntbuf is a single char. I'm assuming here that mntbuf is some sort of record; in that case you want read(fd, (char*)&mntbuf, sizeof mntbuf), not that lint will like that either.
gwyn@smoke.BRL.MIL (Doug Gwyn ) (11/29/88)
In article <1256@vsedev.VSE.COM> logan@vsedev.VSE.COM (James Logan III) writes: >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()? If you look closely, you can see that "lint" is telling you that the usage on line 114 of findlinks.c is inconsistent with line 338 of llib-lc. the latter is the "lint library" that defines the expected types for system interfaces. >directory = (char *)malloc((int)stbuf.st_size); char *malloc(unsigned) according to the lint library. >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)) { int read(int, char *, unsigned) according to the lint library. Case 1 has int for argument 3 Case 2 has the wrong pointer type for argument 2 Case 3 is a bug unless nextentry is a char[].
guy@auspex.UUCP (Guy Harris) (11/30/88)
>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....
paul@devon.UUCP (Paul Sutcliffe Jr.) (12/04/88)
In article <4881@bsu-cs.UUCP> dhesi@bsu-cs.UUCP (Rahul Dhesi) writes: +--------- | [ size argument to malloc/read is (int) on BSD, (unsigned int) on SysV ] | | (Sigh.) You can't always make the same code lint properly under both | SVR2 and 4.3BSD because of this. Damned if I do, unsigned if I don't. +--------- Oh? How about: #ifdef BSD #define SIZE int #else #define SIZE unsigned int #endif ... foo = malloc((SIZE)bar); ... I realize that using the word SIZE may not be appropriate. If you agree with this, substitute your favorite word in its place. - paul -- Paul Sutcliffe, Jr. +---------------------------------+ | Light Year, n.: A regular year | UUCP: paul@devon.UUCP | that has 1/3 less calories. | or : ...rutgers!bpa!vu-vlsi!devon!paul +---------------------------------+
dhesi@bsu-cs.UUCP (Rahul Dhesi) (12/06/88)
I said: (Sigh.) You can't always make the same code lint properly under both SVR2 and 4.3BSD because of this. Damned if I do, unsigned if I don't. In article <1165@devon.UUCP> paul@devon.UUCP (Paul Sutcliffe Jr.) writes: > #ifdef BSD > #define SIZE int > #else > #define SIZE unsigned int > #endif Well, let's respond to this note of despair: (Sigh.) You can't always make the same code compile properly under both C and Pascal. Sure you can: #ifdef LANG_C ... C code ... #else /* LANG_PASCAL */ ... Pascal code ... #endif Now we just run this through a preprocessor (of which there are plenty, some free, others copylefted, and one in /lib/cpp) before submitting it to our favorite compiler. The question still remains: are we compiling the same code, or different code? -- Rahul Dhesi UUCP: <backbones>!{iuvax,pur-ee}!bsu-cs!dhesi