[comp.lang.c] lint vs varargs

jcl@bdrc.UUCP (John C. Lusth) (10/26/89)

I have a lint question. Why does lint complain about varargs stuff?

For example:

 1:	#include <stdio.h>
 2:	#include <varargs.h>
 3:	
 4:	main ()
 5:	
 6:	{
 7:		(void) error ("hello world, says %s\n", "john");
 8:	}
 9:	
10:	error (va_alist)
11:	
12:	va_dcl
13:	
14:	{
15:		va_list ap;
16:		char *format;
17:	
18:		va_start(ap);
19:		format = va_arg(ap, char *);
20:		(void) vprintf (format, ap);
21:		va_end();
22:
23:		return 0;
24:	}

Plain old lint yields:

    test.c(19): warning: possible pointer alignment problem

Linting this beastie with the -c option yields:

    test.c(18): warning: illegal pointer combination
    test.c(19): warning: illegal pointer combination
    test.c(19): warning: possible pointer alignment problem

I'm using a SUN 4, Sun OS 4.0.3. I understand (sorta) the complaint on
line 18, which I think, after macro expansion, casts a pointer to int
to a pointer to char. On a system where int * is bigger than char *
(are there any?), this would fail.  On second thought, however, I just
remembered that (pre-ANSI) char * is guaranteed to be the generic
pointer (i.e. at least as wide as any other pointer).

On line 19, we get a cast of a char * to a char **. No guarantee that
char ** is as wide as char *, so I guess the complaint, while annoying,
is valid.

Would someone explain line 18 to me (and 19 if my reasoning is wrong)?
..and give me a hint on how to shut lint up?

-- 
John C. Lusth, Becton Dickinson Research Center, RTP, NC, bdrc!jcl@mcnc

pag@tcsc3b2.tcsc.com (Philip A. Gross) (10/27/89)

jcl@bdrc.UUCP (John C. Lusth) writes:

>I have a lint question. Why does lint complain about varargs stuff?

[...stuff deleted...]

>Plain old lint yields:

>    test.c(19): warning: possible pointer alignment problem

>Linting this beastie with the -c option yields:

>    test.c(18): warning: illegal pointer combination
>    test.c(19): warning: illegal pointer combination
>    test.c(19): warning: possible pointer alignment problem

>-- 
>John C. Lusth, Becton Dickinson Research Center, RTP, NC, bdrc!jcl@mcnc

John-

You may want to try placing the following comment before your function
which uses varargs.
/* VARARGS */
Most versions of lint will recognize this comment and then properly
ignore the undeclared parameters.  For example,

/* VARARGS */
char	*
make_string (astring, p1, p2, p3, p4, p5, p6, p7 p8 p9)
char	*astring;
{
	static	char	s[80];

	sprintf (s, astring, p1, p2, p3, p4, p5, p6, p7, p8, p9);

	return (s);
}

And thus a call to make_string as shown below:

print_stuff ("foo %s\n", "bar");

would produce:

foo bar

I hope this is of some assistance.  This function 'should' pass lint without
any errors.


===============================================================================
Philip A. Gross       The Computer Solution Co., Inc.       Voice: 804-794-3491
-------------------------------------------------------------------------------
INTERNET:	pag@tcsc3b2.tcsc.com
USENET:		...!tcsc3b2!pag
UUCP:		tcsc3b2!pag	(804)794-1514
ATTMAIL:	attmail!tcsc3b2!pag
-------------------------------------------------------------------------------
        The opinions expressed here are strictly mine and nobody elses.
        << I haven't heard what I have to say about that yet. >> :-)

karl@haddock.ima.isc.com (Karl Heuer) (10/28/89)

In article <1989Oct26.171829.7520@tcsc3b2.tcsc.com> pag@tcsc3b2.tcsc.com (Philip A. Gross) writes:
>You may want to try placing the following comment before your function
>which uses varargs.
>/* VARARGS */
>Most versions of lint will recognize this comment and then properly
>ignore the undeclared parameters.  For example,

Uh, yes, but this has nothing to do with the problem he was having.  You've
"solved" his problem by writing the routine to not use either of the standard
varargs-access mechanisms, resulting in a program that passes lint, but
doesn't work.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

karl@haddock.ima.isc.com (Karl Heuer) (10/28/89)

In article <453@bdrc.UUCP> jcl@bdrc.UUCP (John C. Lusth) writes:
>I have a lint question. Why does [SunOS] lint complain about varargs stuff?
>18:		va_start(ap);
>19:		format = va_arg(ap, char *);
>[without -c:]
>    test.c(19): warning: possible pointer alignment problem
>[with -c, the above and two more:]
>    test.c(18): warning: illegal pointer combination
>    test.c(19): warning: illegal pointer combination
>[After macro expansion, line 18 contains a cast from (int *) to (char *);
>shouldn't this always be legal?]

The problem here is that BSD-based lint, invoked with the -c option, believes
that *any* pointer cast is the moral equivalent of an uncasted assignment to a
non-matching pointer object.  If you can't live with it, don't use -c.

>On line 19, we get a cast of a char * to a char **. No guarantee that
>char ** is as wide as char *, so I guess the complaint, while annoying,
>is valid.

That's essentially correct (and the same problem occurs in USG-based lint).
This warning, and the corresponding one on malloc() calls, could be silenced
by a smarter implementation of lint and/or the header files.  I don't
recommend going to great lengths to fake it out, though.  Instead, I suggest
you report it to your vendor as a lint bug (which it is), and maybe it will
actually be fixed someday.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint