lint suggestion
Ray Butterworth
rbutterworth at watmath.waterloo.edu
Wed Feb 10 00:57:21 AEST 1988
In article <631 at cresswell.quintus.UUCP>, ok at quintus.UUCP (Richard A. O'Keefe) writes:
> There's a feature missing from every Lint I've tried, which would be
> very useful, and should be easy to add (if I had sources, I'd be doing
> it right now). Consider the stdio functions
> In each of these functions, the format argument is almost always a literal,
> and it is very easy by inspecting this literal to determine how many
> arguments should follow and what their types should be. Why not check
> that the arguments are consistent with the format? (This would also help
> to catch unimplemented format items; I wouldn't be surprised to find that
> some of my old programs still contain %r.)
> From: guy at gorodish.Sun.COM (Guy Harris)
> The System V "lint" libraries contain items of the form:
> /*VARARGS1 PRINTFLIKE1*/
> int printf(s) char *s; { return (0); }
> Unfortunately, the System V "lint" doesn't implement "PRINTFLIKE". However, a
> Ninth Edition manual I saw did document "PRINTFLIKE", so maybe it is
> implemented there; then again, "NOSTRICT" was documented in some versions of
> the "lint" manual page although it wasn't implemented.
Good timing. Last week I added a format checker to our highly
modified BSD lint. After I've tested it a bit more, I'll probably
post the change in a few weeks.
I couldn't figure out how to do a /*PRINTFLIKE#*/ directive with the
function definition, since that is looked at in pass2, and by then
the format string used by the calling function is long gone.
Instead, I added a directive to the function declaration. e.g.
extern int printf(/*FORMAT1*/); goes into <stdio.h>.
I tried linting some of the BSD source, but it didn't do much good
since Berkeley seldom bothers to include stdio.h unless the code
won't compile without it, so not many formats were actually checked.
Here's an example of what it does at the moment:
% cat xx.c
#include <stdlib.h>
#include <stdio.h>
main(argv, argc)
{
printf("argc = %ld\n", argc, argv);
printf("argv = %*.*s\n", 12.3, 17L, argv);
printf("%r %d %d\n", 17);
}
% lint xx.c
xx.c:
xx.c(6): warning: format #1 "%ld" requires long, not int
xx.c(6): warning: Too many arguments for format
xx.c(7): warning: format #1 "%*.*" *-width requires int, not double
xx.c(7): warning: format #1 "%*.*s" *-precision requires int, not long
xx.c(7): warning: format #1 "%*.*s" requires string, not int
xx.c(8): warning: unknown #1 "%r" format specifier
xx.c(8): warning: Not enough arguments for format
"main", arg. 2 used inconsistently (int != pointer to pointer to char) xx.c(5) :: llib-lmain:crt0.c(3)
"main" result is used, but none is returned.
"printf" result is always ignored.
More information about the Comp.lang.c
mailing list