[comp.unix.questions] lint won't verify printf formatting against variable types??

stever@tree.UUCP (Steve Rudek) (06/23/89)

I was surprised to discover that neither cc nor lint comments when printf
formatting doesn't match variable types--I thought lint complained about
everything!  In other words, lint won't comment on the following:
int x;
long y;
printf ("x=%ld y=%d", x, y);

I'm trying to get a game called "conquer" to work on a Microport SysV/AT
machine where ints are 16 bits rather than the 32 bits the author expected.
After wrestling with variable overflow for a while, I figured the "good enough"
solution would be to just change most int definitions to INT and #define
INT as long.  Then I would count on cc or lint to detect all the %d formatting
which needed to be changed to %ld.  Wrongo.  cc and lint are both completely
blind to the misformatting!  I find that incredible.  Oh, I understand that
the formatting argument to printf is just a string pointer, but I'm aghast
that there appears to be no easy way to detect what must be a super common
coding bug!  The printf family is enough of a fixture in the C language and
this is a common enough sort of error that lint really should be responsible
for catching this sort of misformat.

Am I missing something or do I really need a custom program to detect this
kind of mistake?  If so, do I have to write it myself or has someone out
there already written the program??

P.S. Can anyone direct me to Ed Barlow, the author of "conquer", or to the
latest version?  I'm hacking on version 2.2.
-- 
----------
Steve Rudek  {ucbvax!ucdavis!csusac OR ames!pacbell!sactoh0} !tree!stever

ked@garnet.berkeley.edu (Earl H. Kinmonth) (06/24/89)

In article <328@tree.UUCP> stever@tree.UUCP (Steve Rudek) writes:

>I was surprised to discover that neither cc nor lint comments when printf
>formatting doesn't match variable types--I thought lint complained about
>everything!  In other words, lint won't comment on the following:
>int x;
>long y;
>printf ("x=%ld y=%d", x, y);
>
>I'm trying to get a game called "conquer" to work on a Microport SysV/AT
>machine where ints are 16 bits rather than the 32 bits the author expected.

One way to make sure code like this is reasonably portable is to always
write the format statement with casts.

printf ("x=%ld y=%d", (long) x, (int) y);

or preferably

printf ("x=%ld y=%ld", (long) x, (long) y);

A superfulous cast does not harm.  Casting to a larger size makes sure
nothing will be lost.

chris@mimsy.UUCP (Chris Torek) (06/24/89)

In article <328@tree.UUCP> stever@tree.UUCP (Steve Rudek) writes:
>I was surprised to discover that neither cc nor lint comments when printf
>formatting doesn't match variable types ....

There are a whole bunch of `cc's and `lint's.  The lint in 4.3BSD-tahoe
*does* complain, courtesy of Arthur Olson (uunet!elsie!ado).  Become a
student at your nearby University, get an account on a Tahoe or VAX
running 4.3-tahoe, and lint your programs there. :-)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

jagardner@watmath.waterloo.edu (Jim Gardner) (06/24/89)

Not this this will help you, but we just put this kind of checking into
our (ANSI aspiring) compiler. I'm sure there are many other vendors who
will be doing (or have done) this, since your's is a common complaint.
Maybe you can bash on the gcc people for it...

David Tanguay

buck@siswat.UUCP (A. Lester Buck) (06/26/89)

In article <328@tree.UUCP>, stever@tree.UUCP (Steve Rudek) writes:
> I was surprised to discover that neither cc nor lint comments when printf
> formatting doesn't match variable types--I thought lint complained about
> everything!  In other words, lint won't comment on the following:
> int x;
> long y;
> printf ("x=%ld y=%d", x, y);
> 
> I'm trying to get a game called "conquer" to work on a Microport SysV/AT
> machine where ints are 16 bits rather than the 32 bits the author expected.

The Nutshell handbook "Checking C Programs with Lint" discusses this
problem.  Until we all have versions of lint that handle /*PRINTFLIKEn*/,
you might try using the program printfck.  "Andries Brouwer wrote this as a
quick hack to check the Hack & Quest sources."  It rewrites each printf-like
call to have the arguments as return values from functions, and then
includes a lint library for each function type.  This program, and several
more lint helper programs, are available from uunet!~/nutshell/lint/*.

I was writing some drivers on an RT under AIX 2.2.1 recently and had been
running them through lint regularly (after cobbling together a lint library
for kernel routines).  Then I was reading the Nutshell handbook above and
picked up one of the extended checkers (the one called "check", if I
remember).  It reported that I had a nested comment in the source, but I
thought that was rather odd.  Then I noticed that the nested comment was
reported in the system header file!#%$  Sure enough, here is a piece of
/usr/include/sys/kio.h from AIX/RT 2.2.1:

[ declaring a struct query ]

	caddr_t ccb;
	long ioard;
	union {
		struct {                /* disk device mini disk and floppy */
			long blk_num;    /* block # of last operation */
			long num_blks;   /*
				       ^^^^^^^
			char blk_size;   /* block size */
			char dev_add[3]; /* 24 bit physical device address */
			} vd;
		struct {                /* floppy device */
			long blk_num;    /* block # of last operation */
			char byte_sec;  /* bytes per sectors */
			char sec_track; /* sectors/track */
			char track_cyl; /* tracks per cylinder */
			char num_cyl;   /* number of cylinders */
			char blk_size;  /* block size in bytes */
			char res;
			ushort steprate;
			} fd;
		struct {                /* rs232 device */
			char c1;

Such discoveries send a chill down my spine.  I can think of several
possibilities, all bad, but the most likely is that the released version of
the headers is separated at some point from the "one true source" for AIX.
What other subtle bugs might have crept in with such a source code control
system?  Does this happen in other versions of Unix?

-- 
A. Lester Buck		...!texbell!moray!siswat!buck

bob@omni.com (Bob Weissman) (06/27/89)

Last week I spent an entire day tracking down one of those bugs you just
don't see after staring at your code too long.  It was of the form:

	if (condition);
	    action;

My lint (SunOS 4.0.1 version) did not flag the extra semicolon.

I Hate C.


-- 
Bob Weissman
Domainish: bob@omni.com
UUCPish:   ...!{amdahl,apple,pyramid,tekbspa,uunet}!koosh!bob