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