Path: utzoo!mnetor!uunet!husc6!bloom-beacon!gatech!hao!noao!mcdsun!mcdchg!clyde!watmath!rbutterworth From: rbutterworth@watmath.waterloo.edu (Ray Butterworth) Newsgroups: comp.lang.c Subject: Re: lint suggestion Message-ID: <16791@watmath.waterloo.edu> Date: 9 Feb 88 14:57:21 GMT References: <631@cresswell.quintus.UUCP> Organization: U of Waterloo, Ontario Lines: 59 Keywords: printf-"prototype" In article <631@cresswell.quintus.UUCP>, ok@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@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 . 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 #include 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.