Dead functions and /*NOTREACHED*/

karl at haddock karl at haddock
Tue Sep 9 05:47:00 AEST 1986


sun!guy (Guy Harris) writes:
>complaints about "possible pointer alignment problems" when "malloc" is used
>are pure noise.

Certainly.  I guess the addition of a lint comment (on the *declaration* of
malloc, not its use, of course) is a pretty clean way to handle it.  A
pointer type that (unlike "void *") is guaranteed to be fully aligned would
solve it too (and be more efficient on word-addressible machines), but since
only malloc et al would use it, it's not worth a language change.

>Nothing prevents a compiler or "lint" from treating *all* "void *" pointers
>as always being properly aligned;

If you mean a compiler can generate code assuming "void *" is always aligned,
you're wrong -- the user can legally stuff a "char *" value into a "void *"
object.  I assume you mean the compiler/lint can be silent about uncasted
assignments like "intp = voidp".

>the most common uses of "void *" are [malloc and] when a data structure is
>used [as a pseudo-union of pointers] - in this case, the compiler can't do
>the checking properly anyway, so warnings are largely useless.

The former is actually a special case of the latter, the only difference
being that the result is known to be maximally aligned.  I think the only
other functions that return "void *" (in X3J11 01-May-1986) are those like
bsearch() and memcpy(), which expect arguments of arbitrary pointer type
cast into "void *", and return the same.  The problem is that the compiler
isn't smart enough to know that "(int *)memcpy((void *)intp, (void *)intp);"
is correct whereas "voidp = (void *)charp; intp = (int *)voidp;" is likely
to cause trouble.  In my opinion, the best solution is to assume that the
user knows what he's doing if an explicit cast is present, and otherwise
give a warning message.  (Likewise for using an int in a float context.)

Btw, I sometimes handle the malloc problem with the (ANSIfied) code below,
which can easily be modified for other functions like memcpy().

#ifdef lint
extern int    *imalloc(unsigned int);
extern double *dmalloc(unsigned int);
#else
extern void   *malloc(unsigned int);
#define imalloc(n) ((int    *)malloc((n)*sizeof(int)))
#define dmalloc(n) ((double *)malloc((n)*sizeof(double)))
#endif

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



More information about the Comp.lang.c mailing list