[net.unix-wizards] casts

NEP.FOUTS@Ames-Vmsb.ARPA (03/23/84)

The C program d.c:
              
( 1)		char * malloc( );
( 2)		struct x {
( 3)			int a; 
( 4)		};      
( 5)		main(){ 
( 6)			struct x *p;
( 7)			p = (struct x *)malloc((unsigned) sizeof (struct x));
( 8)			free((char *)p);
( 9)		}       
              
(line numbers appended for reference.) run through lint with the command:
              
		lint -c d.c 
              
Gives the output:
              
		d.c:        
		d.c(7): warning: illegal pointer combination
		d.c(8): warning: illegal pointer combination
              
The problem apparently being that p is a pointer to a structure of type x,
while malloc(3) returns a pointer to an array of characters.  According to
[1], this construction is ". . . the safest course . . ."  If this is so,
why does lint generate the "illegal pointer combination" messages, and
wht is a better way (short of writing memory allocation routines for each
structure in the program) to handle this problem?
              
I realize that using the '-c' option on lint is supposed to complain about
casts, as described in [2], but I guess the real question is how to define
a mechanism for "portable casts" which allows those casts which can be moved
from one place to another to do so.
              
Or, perhaps, I don't understand the use of casts.  It appears to me that a
cast is supposed to be the "safe" way to do data type conversion.  It also
appears that pointers are a type where it should be possible for the system
to do this conversion.

By the way, is there a C implementation in which this particular use of
malloc(3) will fail?
              

-----         
[1] The C Programming Language; Kernighan, Brian W. and Ritchie, Dennis M.,
    Prentice-Hall, Inc., Englewood, Cliffs, New Jersey; Chapter 6, page 134
              
[2] Lint, a C Program Checker; (in Unix Programmer's Manual, Seventh Edition,
    Volume 2a, January, 1979); S. C. Johnson, Bell Laboratories,
    Murray Hill, New Jersey, page 4
------

gwyn@Brl-Vld.ARPA (03/23/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@Brl-Vld.ARPA>

Don't worry; your use of casts on malloc()ed pointers is fine.
The warnings would be valid if it were not for the fact that
malloc() is carefully designed to return pointers to storage
that is aligned stringently enough that the (char *) can be
safely cast to (anything *).  "lint" does not know how malloc()
was designed so it warns about coercing (char *) to (anything *)
and back since that is IN GENERAL unsafe.  It happens not to be
a problem in this case, so ignore the warnings.

The C Language Standards Committee was talking about adding
(void *) to the language as a generic pointer type.  Perhaps
that will eventually help...

jerry@oliveb.UUCP (Jerry Aguirre) (04/05/84)

One problem, from lint's point of view, with:

	p = (struct foo *)malloc(size);

is that when casting a char pointer into a pointer to a larger size
opject there is no guarantee that the pointer is aligned.  A char
pointer can be odd while most machines require an even pointer for
ints and larger types.  Of course malloc is guaranteed to return
a pointer which has worst case alignment.  The problem is that lint
does not know this.  The manual calls these "questionable" casts.
Not wrong, just not guaranteed right.

I fooled around with this while working to make a program squeaky
clean.  I finally wrote a small procedure to do the malloc and
cast, returning a pointer of the type I needed.  This reduced
the lint errors to just 1 place.  I had no luck getting our version
of lint to shut off type checking for that procedure.  The NOSTRICT
option did not work (a strings on lint shows it doesn't even have
that option).

					    Jerry Aguirre
    {hplabs|fortune|ios|tolerant|allegra|tymix}!oliveb!jerry