delbene@homxa.UUCP (K.DELBENE) (07/18/85)
I've got a dumb question on the dynamic allocation of memory to structures in 'C' using the malloc() family. It seems that no matter how I declare the function calloc() or how I typecast in the returned pointer, I get a warning from lint that I have a "possible pointer alignment problem." Since I'm writing a simulation, with these structures coming and going in volume, I have to use dynamic allocation. My question is, what problems am I going to run into and how can I fix them (or should I just ignore the the message)? Kurt D. Del Bene ...!ihnp4!homxa!delbene P.S. Please be gentle. I know 'C' (2 yrs. experience, 10k+ lines), but not its nuances. P.P.S. Anyone know of a GOOD (i.e. well written) book on 'C' (other than K&R, which I've read and digested relatively completely) that doesn't treat you like some weekend programmer with a business degree from Podunk U?
henry@utzoo.UUCP (Henry Spencer) (07/19/85)
> ... It seems that no > matter how I declare the function calloc() or how I typecast in > the returned pointer, I get a warning from lint that I have > a "possible pointer alignment problem." ... what problems > am I going to run into and how can I fix them (or should I just > ignore the the message)? Ignore the messages. Lint is saying "you are casting one kind of pointer to another, and this is an area where portability problems can occur"; it doesn't know that malloc() and friends are a special case where this sort of thing is guaranteed to be safe. This particular message is enough of a pain that the "lint" entry in the Makefile for any program of mine that uses malloc() a lot tends to read something like: lint foo bar bletch | egrep -v 'possible pointer alignment' One should do this sort of thing with fear and trepidation, but it is unfortunately true that *real* lint problems are much easier to spot when they aren't buried in a river of meaningless complaints about malloc(). -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
chris@umcp-cs.UUCP (Chris Torek) (07/20/85)
Lint doesn't realize that malloc and calloc have been written such
that that "possible pointer alignment problem" never occurs. The
thing to do is ignore the message (or teach lint how to say that
a function returns a ``very aligned'' pointer; someone once suggested
using /*ALIGNOK*/ similar to the way /*NOTREACHED*/ and /*ARGSUSED*/
tell lint not to complain).
Another alternative is to use code like this:
struct foo *
getfoo()
{
struct foo *p;
#ifdef lint
p = NULL;
#else
p = (struct foo *)malloc((unsigned)sizeof (struct foo));
if (p == NULL)
error(1, errno, "out of memory in getfoo");
p->this = p->that = theotherthing;
#endif
return (p);
}
since lint knows that ``p = 0'' is not assigning an unaligned pointer
to p. Of course this loses the type checking in the rest of the
code. (Sigh.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP: seismo!umcp-cs!chris
CSNet: chris@umcp-cs ARPA: chris@maryland
gwyn@BRL.ARPA (VLD/VMB) (07/21/85)
Unless someone has patched your version of "lint" to handle malloc() as a special case, there is no way to avoid warnings about possible pointer alignment problems. That is because casting from a (char *) to a (foo *) is not possible in general. Malloc() has been specially designed to ensure that its returned (char *) IS properly aligned for anything whatsoever. "lint" does not normally know this. By the way, I would discourage using calloc() unless you are allocating an array of (char)s and want them to all be NUL bytes. Since calloc() cannot guess how you are intending to use the storage it allocates, it is unable to fill it with the "right" type of 0 data. You will normally be better off using malloc() and initializing the storage yourself. There aren't many good books in C for the non-novice. You might look at Narain Gehani's "Advanced C: Food for the Educated Palate" (Computer Science Press, 1985).
ksbszabo@watvlsi.UUCP (Kevin Szabo) (07/22/85)
>> ... It seems that no >> matter how I declare the function calloc() or how I typecast in >> the returned pointer, I get a warning from lint that I have >> a "possible pointer alignment problem." What options are you passing to LINT? If you are on a BSD system, don't use the -c option. If you are on sys3/sys5 use the -c option. Henry Spencer says: >Ignore the messages... >...the "lint" entry in the Makefile for any program >of mine that uses malloc() a lot tends to read something like: > lint foo bar bletch | egrep -v 'possible pointer alignment' Actually, you can get LINT to do a little bit more checking for you, and thereby find a few of those irritating little bugs where you allocate a structure of the wrong size while casting it to the correct pointer type. I find that LINT generally believes a cast to a pointer type, as long as you don't/do use the -c option (on a BSD/SYSIII system). The -c option tells lint to complain (or not complain) about all non-portable pointer mismatches and questionable pointer casting. You can then automatically allocate a structure and cast it using a nice little macro: #define ALLOC( x ) ((x *) malloc( sizeof(x))) and a companion: #define FREE( x ) free((char *) ( x )) The ALLOC macro behaves like pascal's "new( x )" builtin, and reduces the chances of a typographical error such as: ptr_type1 = (ptr_type1) malloc( sizeof (type2)); We started using the macros after we spent two days searching for exactly this type of error. Argh. Kevin -- Kevin Szabo' watmath!wateng!ksbszabo (U of W VLSI Group, Waterloo, Ont, Canada)
guy@sun.uucp (Guy Harris) (07/22/85)
> Lint doesn't realize that malloc and calloc have been written such > that that "possible pointer alignment problem" never occurs. The > thing to do is ignore the message (or teach lint how to say that > a function returns a ``very aligned'' pointer; someone once suggested > using /*ALIGNOK*/ similar to the way /*NOTREACHED*/ and /*ARGSUSED*/ > tell lint not to complain). Hopefully, pointers of the ANSI C type "void *" will be able to be assigned to any other pointer type without any complaints, including complaints about possible alignment problems. This is, of course, a horribly large loophole, but there may be some small hope that people won't abuse it and will always write routines like "malloc" which return "void *" values to align the object pointed to so that it can, indeed, be used to point to anything. Guy Harris
arnold@ucsfcgl.UUCP (Ken Arnold%CGL) (07/22/85)
In article <921@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes: >Lint doesn't realize that malloc and calloc have been written such >that that "possible pointer alignment problem" never occurs. The >thing to do is ignore the message (or teach lint how to say that >a function returns a ``very aligned'' pointer; someone once suggested >using /*ALIGNOK*/ similar to the way /*NOTREACHED*/ and /*ARGSUSED*/ >tell lint not to complain). There is the (as far as I know unimplemented but) documented /*NOSTRICT*/. This seems to have been added to handle this kind of case, but I have never, on any version of lint I've used, seen it actually work. This WOULD be a good solution. Ken Arnold
mff@wuphys.UUCP (Swamp Thing) (07/22/85)
In article <921@umcp-cs.UUCP> chris@umcp-cs.UUCP (Chris Torek) writes: >Lint doesn't realize that malloc and calloc have been written such >that that "possible pointer alignment problem" never occurs. The >thing to do is ignore the message (or teach lint how to say that >a function returns a ``very aligned'' pointer; someone once suggested >using /*ALIGNOK*/ similar to the way /*NOTREACHED*/ and /*ARGSUSED*/ >tell lint not to complain). It seems to me that the thing to do is change or eliminate malloc and calloc. It seems like a small price to pay to satisfy the great and powerful LINT. Hardly any change at all compared to creating an entire new variable type! Mark F. Flynn Department of Physics Washington University St. Louis, MO 63130 ihnp4!wuphys!mff "Into the void boys, into the void."
henry@utzoo.UUCP (Henry Spencer) (07/22/85)
> ... I find that LINT generally believes a cast to a pointer > type, as long as you don't/do use the -c option (on a BSD/SYSIII system). > The -c option tells lint to complain (or not complain) about all > non-portable pointer mismatches and questionable pointer casting. Sigh, not so on a V7, which is why I mentioned the "grep -v" approach. The absence of -c does *not* tell the V7 lint to shut up about possible alignment problems. -- Henry Spencer @ U of Toronto Zoology {allegra,ihnp4,linus,decvax}!utzoo!henry
tp@ndm20 (07/30/85)
>I just realised a major problem with (void *). On machines like the HP-1000 >a pointer to a byte and a pointer to a word don't have the same bit-pattern. That is probably try of ANY machine which is addressed by some unit larger than a byte. We use a Harris H series computer, which is word addresseable (24-bit words, even), and a pointer to a char definately does NOT look like a pointer to anything else. You have to cast them properly. I don't know about void, as I haven't seen the ANSI C draft, but on the Harris, anything that returns a "generic" pointer must return a char pointer with word alignment. It then MUST be cast to the appropriate type (which reformats the pointer properly). A pointer to void would presumably have to use the same approach.