[comp.unix.questions] Shutting lint up about malloc

jr@amanue.UUCP (Jim Rosenberg) (05/17/87)

This is driving me nuts.  I can't get lint on my system to shut up about
malloc.  In response to the following code:

#include <stdio.h>

struct foo {
	int foo1;
	char foo2;
};

extern char *malloc();

struct foo *goo()
{
	struct foo *p;

	/*NOSTRICT*/
	if ((p = (struct foo*) malloc(sizeof(struct foo))) == NULL) {
		(void) fprintf(stderr, "Out er memory, turkey\n");
		return NULL;
	}
	return p;
}

the command lint -u prints:

warning: possible pointer alignment problem
    (15)  	

Aargh!!  The man page for malloc() sayeth:  "malloc returns a pointer to
a block of at least _size_ bytes suitably aligned for any use".  Right.
lint apparently doesn't capiche that malloc() strains itself most mightly
to achieve this.  Well, OK, so my lint is too dumb to know about malloc(),
which arguably it should, what about /*NOSTRICT*/ -- isn't this supposed
to turn off this kind of message??  The tutorial for lint says:

"If it is desired to turn off strict type checking for an expression, the
comment

	/* NOSTRICT */

should be added to the program immediately before the expression."

Right.  Well it didn't tell lint to please unsquawk.  My system is VENIX
System V, which is a pretty straight V.2 except for implementing its own
shared memory calls and the /usr/group locking standard -- one would think
it would be an off-the-tape lint.  It can't be *that* ancient since it does
seem to know about void.  strings run on the file /usr/lib/lint1 produces
the following: (line numbers added)

	57:123456789
	58:VARARGS
	59:LINTLIBRARY
	60:ARGSUSED
	61:NOTREACHED
	62:yylex error, character %03o (octal)

Hmm.  No NOSTRICT.  grepping for STRICT in the strings listing yields
nothing.  Same for /usr/lib/lint2.  So it sort of looks as though /*NOSTRCT*/
got dumped from my version of lint.

(1) Did /*NOSTRICT*/ get dropped somewhere?  If so, was this a mistake?  If
not, can someone tell me **WHY**??  (2) Absent /*NOSTRICT*/ how the devil
am I supposed to get lint to shut up about casting the value returned by
malloc() to a struct <whatever> *?  The cast makes it clear what I mean and
the man page says I can do it.

I have some code that would completely pass lint but for this annoyance.

gregg@a.cs.okstate.edu (Gregg Wonderly) (05/18/87)

in article <61@amanue.UUCP>, jr@amanue.UUCP (Jim Rosenberg) says:
> 
> This is driving me nuts.  I can't get lint on my system to shut up about
> malloc.  In response to the following code:
> 
   ......
> 
>   /*NOSTRICT*/
>   if ((p = (struct foo*) malloc(sizeof(struct foo))) == NULL) {
>       (void) fprintf(stderr, "Out er memory, turkey\n");
>       return NULL;
>   }

Try making this

                                                          %%%%%%%%%%%%%%
    if ((p = (struct foo*) malloc(sizeof(struct foo))) == (struct foo *)NULL) {
        (void) fprintf(stderr, "Out er memory, turkey\n");
        return NULL;
    }

Comparing a structure pointer (namely p) against NULL (sometimes declared as
((char *)0) is probably biting you.


-----
Gregg Wonderly
Department of Computing and Information Sciences
Oklahoma State University

UUCP: {cbosgd, ea, ihnp4, isucs1, mcvax, uokvax}!okstate!gregg
ARPA:  gregg@A.CS.OKSTATE.EDU

chris@mimsy.UUCP (Chris Torek) (05/18/87)

>in article <61@amanue.UUCP> jr@amanue.UUCP (Jim Rosenberg) says:
>>... I can't get lint on my system to shut up about malloc. ...
>>   /*NOSTRICT*/
>>   if ((p = (struct foo*) malloc(sizeof(struct foo))) == NULL) {

In article <1994@a.cs.okstate.edu> gregg@a.cs.okstate.edu (Gregg
Wonderly) writes:
>Try making this
>    if ((p = (struct foo*) malloc(sizeof(struct foo))) == (struct foo *)NULL) {
>Comparing a structure pointer (namely p) against NULL (sometimes declared as
>((char *)0) is probably biting you.

Nope.  If NULL has been defined as `(char *)0', it is wrong and should
be changed (to just `0'), but lint will still complain.

Jim Rosenberg was on target with his `strings' on lint.  He noted that
this unearthed (unoxided?) `VARARGS' and `ARGSUSED' and `NOTREACHED',
but not `NOSTRICT'.  Why?  Because it is *not* *there*.

NOSTRICT is documented but not implemented in most `lint's.  I have
used two different tactics:

	${LINT} ${LINTFLAGS} ${SOURCES} | \
	grep -v 'possible pointer alignment problem'

and

	#ifdef lint
		{ static struct foo oof; p = &oof; }
	#else
		p = (struct foo *) malloc(sizeof (struct foo));
	#endif
		if (p == NULL)
			...

Neither is pretty; nor, for that matter, is /*NOSTRICT*/.  The
proper solution is to convince lint that pointers returned by malloc
are properly aligned for all data types.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	seismo!mimsy!chris

guy%gorodish@Sun.COM (Guy Harris) (05/18/87)

> Comparing a structure pointer (namely p) against NULL (sometimes declared as
> ((char *)0) is probably biting you.

The amount of misinformation circulating on USENET about null
pointers is both awesome and depressing.  ANY COMPILER THAT CAN'T
PROPERLY HANDLE

	struct foo *p;

	if (p == 0)

(i.e., won't compile it into a comparison of "p" with a null pointer
of the proper type) IS NOT A VALID C COMPILER.  ANY IMPLEMENTATION OF
C THAT DEFINES NULL AS "(char *)0" IS AN INVALID C IMPLEMENTATION.

Furthermore, if the implementation is illegally defining NULL as
"(char *)0", casting NULL to "(struct foo *)NULL" will elicit a
complaint from "lint", so that won't even fix the problem!

The complaint he is getting from "lint" is NOT "illegal pointer
combination", it's "possible pointer alignment problem".  "lint" is
NOT complaining about the comparison of "p" with NULL.  It is
complaining about the casting of the result of "malloc" to type
"struct foo *".

The reason why NOSTRICT doesn't work is that, to the best of my
knowledge, it has never been implemented, not that it was dropped.
As for why it was never implemented, I don't know; try asking Steve
Johnson - I think he's working at the Dana Group now.

Unfortunately, there's no way to silence "lint" in this case.  In the
S5R2 version, both the "-h" and "-p" flags turn on the check for
possible alignment problems.  Perhaps when ANSI C becomes a standard,
"lint" will not complain about alignment problems when converting
"void *" pointers.

forys@sigi.Colorado.EDU (Jeff Forys) (05/18/87)

In article <1994@a.cs.okstate.edu> gregg@a.cs.okstate.edu
(Gregg Wonderly) writes:
> Try [casting the NULL pointer] making this
>    if ((p = (struct foo*) malloc(sizeof(struct foo))) == (struct foo *)NULL) {
>        (void) fprintf(stderr, "Out er memory, turkey\n");
>        return NULL;
>    }
> Comparing a structure pointer (namely p) against NULL (sometimes declared
> as ((char *)0) is probably biting you.

No, that's perfectly legal without casting NULL -- unless the C compiler is
brain damaged (K&R, pg 98).  The problem here is 2 fold:
1) His version of lint doesnt know that the C compiler will align pointers
   to differnt types (4.3BSD lint understands this).
2) the /*NOSTRICT*/ directive is probably not implemented in his version of
   lint (it's unimplemented in 4.3BSD as well).
---
Jeff Forys @ UC/Boulder Engineering Research Comp Cntr (303-492-6096)
forys@Boulder.Colorado.EDU  -or-  ..!{hao|nbires}!boulder!forys

bradley@uiucdcsm.cs.uiuc.edu (05/19/87)

Are you using the -h flag with lint?  With our lint pointer alignment
messages are generated with the -h flag but not without.  It appears that
this is one of the heuristics that -h invokes.  

By the way, if I understand NOSTRICT correctly it just tells list to
ignore type conflicts.  I wonder if it would help in this case, since no 
type conflict exists (becuase you're doing explicit casting)?

gwyn@brl-smoke.ARPA (Doug Gwyn ) (05/19/87)

I know of no way to keep the SVR2 "lint" from warning about possible
type mismatch when converting pointers returned by malloc.

However, you might consider implementing separate functions to
allocate storage for each of your data types, which at least would
isolate the warnings to one place in the code:

...
	foo *p, *foo_alloc();
...
	p = foo_alloc();
...
foo *
foo_alloc()
	{
	extern void fatal();	/* application utility routine */
	extern char *malloc();
	register char *p = malloc( sizeof(foo) );
	/* the following check may not be suitable for your application */
	/* (it's a strategic decision enforced in a low-level routine) */
	if ( p == NULL )
		fatal( "out of space" );	/* give up */
	return (foo *)p;	/* ignore "lint" warning here */
	}

wen-king@cit-vlsi.Caltech.Edu (Wen-King Su) (05/19/87)

In-Reply-To: <61@amanue.UUCP>

Cc:

Bcc:


In article <61@amanue.UUCP> you write:
*>This is driving me nuts.  I can't get lint on my system to shut up about
*>malloc.

*>(1) Did /*NOSTRICT*/ get dropped somewhere?  If so, was this a mistake?  If
*>not, can someone tell me **WHY**??  (2) Absent /*NOSTRICT*/ how the devil
*>am I supposed to get lint to shut up about casting the value returned by
*>malloc() to a struct <whatever> *?  The cast makes it clear what I mean and
*>the man page says I can do it.

I do not know about /*NOSTRICT*/, but this is how I get malloc to shut up:

#ifdef lint
#define malloc(n) MALLOC(n)
extern long *MALLOC();	/* use a type with the most strict alignment */
#endif /*lint*/

You may need to define an empty "MALLOC" function to keep lint happy.


=============================================================================
You have a strange feeling that your boss is watching you over your shoulder.

                                                  ----------
                                                ##+.?......|
                                                # |..%.%%..|
                                              ### |........|
                                              #   |......?.|
                                            ###   -----+----
                                            #          #################
                                            #                       ---+-
       -------------           ``###############                    |...|
       |...*.......|           %------------#           #           |.=.|
       |...*.......+############|..N.......|#      --------        #+...|
       |...........|          ##|....././..|#      |.....>|      ###-----
       |...`..]....+############+..........|#      |......|      # 
       |...........|           #|.c.@....^.|#######+......+#######
       |........<..+############|.......d..+#      |......|
       -------------            ------------       --------

Level 10   Hp  44(44)   Ac 3    Str 18/37   Exp  9

=============================================================================
You have a strange feeling that your boss is watching you over your shoulder.

                                                  ----------
                                                ##+.?......|
                                                # |..%.%%..|
                                              ### |........|
                                              #   |......?.|
                                            ###   -----+----
                                            #          #################
                                            #                       ---+-
       -------------           ``###############                    |...|
       |...*.......|           %------------#           #           |.=.|
       |...*.......+############|..N.......|#      --------        #+...|
       |...........|          ##|....././..|#      |.....>|      ###-----
       |...`..]....+############+..........|#      |......|      # 
       |...........|           #|.c.@....^.|#######+......+#######
       |........<..+############|.......d..+#      |......|
       -------------            ------------       --------

Level 10   Hp  44(44)   Ac 3    Str 18/37   Exp  9

ado@elsie.UUCP (Arthur David Olson) (05/19/87)

> The reason why NOSTRICT doesn't work is that, to the best of my
> knowledge, it has never been implemented, not that it was dropped.

Those who'd like to give it a try may find the letter below
(slightly edited from its original form) of interest.
As others have noted, a better approach to malloc/calloc messages
may be for lint to remain silent on pointer assignments involving (void *);
the NOSTRICT mechanism is more generally useable (and abuseable).

+ From ado Fri Apr 17 15:40:38 1987
+ Subject: Re:  lint...
+ 
+ > Also, speaking of man pages, how tough would /*NOSTRICT*/ be?
+ 
+ Well, a simple-minded implementation of NOSTRICT isn't too bad.
+ First, we add this code to "lib/mip/scan.c" to recognize NOSTRICT in comments,
+ setting the variable "strictnein":
+ 
+ 			case 'N':
+ 				lxget( c, LEXLET );
+ 	#ifndef ASWAS
+ 				if (strcmp(yytext, "NOSTRICT") == 0) {
+ 					extern int	strictnein;
+ 
+ 					strictnein = 1;
+ 					continue;
+ 				}
+ 	#endif /* !ASWAS */
+ 				if( strcmp( yytext, "NOTREACHED" ) ) continue;
+ 				reached = 0;
+ 				continue;
+ 
+ Second, we visit "ecode" in "lint.c",
+ arranging things so that each time the compiler emits code strictnein gets
+ turned off:
+ 
+ 	#ifndef ASWAS
+ 	int	strictnein;
+ 	#endif /* !ASWAS */
+ 	ecode( p ) NODE *p; {
+ 		/* compile code for p */
+ 
+ 		fwalk( p, contx, EFF );
+ 		lnp = lnames;
+ 		lprt( p, EFF, 0 );
+ 	#ifndef ASWAS
+ 		strictnein = 0;
+ 	#endif /* !ASWAS */
+ 		}
+ 
+ Finally, we conditionalize the appropriate error messages based on strictnein.
+ The big payoff place for doing this is in "lib/mip/trees.c", in the function
+ "chkpun":
+ 
+ 	chkpun(p) register NODE *p; {
+ 	...
+ 		register NODE *q;
+ 		register t1, t2;
+ 		register d1, d2;
+ 	#ifndef ASWAS
+ 	#ifdef LINT
+ 		extern int	strictnein;
+ 	#endif /* LINT */
+ 	#endif /* !ASWAS */
+ 	...
+ 	#ifndef ASWAS
+ 	#ifdef LINT
+ 			if (!strictnein)
+ 	#endif
+ 	#endif /* !ASWAS */
+ 			werror( "illegal pointer combination" );
+ 		}
+ 
+ 	}
+ 
+ You might also want to conditionalize some other messages.
+ 
+ If the above approach is used, the manual page description of NOSTRICT needs
+ to say that it shuts off strict checking in the next "statement or
+ conditional", rather than in the next "expression."
--
UNIX is a registered trademark of AT&T.
Lint is a trademark of Oscar Madison.
-- 
	UUCP: ..seismo!elsie!ado	   ARPA: elsie!ado@seismo.CSS.GOV
	     Elsie and Ado are trademarks of Borden, Inc. and Ampex.

chuckles@aoa.UUCP (Charles Stern) (05/19/87)

In article <61@amanue.UUCP> jr@amanue.UUCP (Jim Rosenberg) writes:
>This is driving me nuts.  I can't get lint on my system to shut up about
>malloc.  In response to the following code:
>
>#include <stdio.h>
>
>struct foo {
>	int foo1;
>	char foo2;
>};
>
>extern char *malloc();
>
>struct foo *goo()
>{
>	struct foo *p;
>
>	/*NOSTRICT*/
>	if ((p = (struct foo*) malloc(sizeof(struct foo))) == NULL) {
>		(void) fprintf(stderr, "Out er memory, turkey\n");
>		return NULL;
>	}
>	return p;
>}
>
>the command lint -u prints:
>
>warning: possible pointer alignment problem
>    (15)  	
>
>Aargh!!  The man page for malloc() sayeth:  "malloc returns a pointer to
>a block of at least _size_ bytes suitably aligned for any use".  Right.
>lint apparently doesn't capiche that malloc() strains itself most mightly
>to achieve this.  Well, OK, so my lint is too dumb to know about malloc(),
>which arguably it should, what about /*NOSTRICT*/ -- isn't this supposed
>to turn off this kind of message??  The tutorial for lint says:
>
>"If it is desired to turn off strict type checking for an expression, the
>comment
>
>	/* NOSTRICT */
>
>should be added to the program immediately before the expression."
>
>Right.  Well it didn't tell lint to please unsquawk.  My system is VENIX
>System V, which is a pretty straight V.2 except for implementing its own
>shared memory calls and the /usr/group locking standard -- one would think
>it would be an off-the-tape lint.  It can't be *that* ancient since it does
>seem to know about void.  strings run on the file /usr/lib/lint1 produces
>the following: (line numbers added)
>
>	57:123456789
>	58:VARARGS
>	59:LINTLIBRARY
>	60:ARGSUSED
>	61:NOTREACHED
>	62:yylex error, character %03o (octal)
>
>Hmm.  No NOSTRICT.  grepping for STRICT in the strings listing yields
>nothing.  Same for /usr/lib/lint2.  So it sort of looks as though /*NOSTRCT*/
>got dumped from my version of lint.
>
>(1) Did /*NOSTRICT*/ get dropped somewhere?  If so, was this a mistake?  If
>not, can someone tell me **WHY**??  (2) Absent /*NOSTRICT*/ how the devil
>am I supposed to get lint to shut up about casting the value returned by
>malloc() to a struct <whatever> *?  The cast makes it clear what I mean and
>the man page says I can do it.
>
>I have some code that would completely pass lint but for this annoyance.


This may be a rather simplistic answer to your question, but I suggest 
taking your assignment of p OUT of the conditional statement.  For some
reason, if I am writing shell scripts or C code, and I do something more
complex than comparing two objects, the compiler throws up (Vax 8650
running Ultrix 2.1).  This is the easiest answer I can give you, since I
*DON'T* write device drivers using cat>. :-#) (See an article a couple of
weeks ago defining various user levels.)

Chuckles
-- 
                    |                                     \  |  /
         /\      -------      /\                           \ | /
        /  \    |   |   |    /  \                           \|/
------ /----\---|---|---|---/----\---------------------------|---
      /      \  |   |   |  /      \                         /|\
     /        \  -------  /        \                       / | \
                    |                                     /  |  \
             
	Charles Stern
	...!{decvax,linus,ima,ihnp4}!bbncca!aoa!chuckles
	...!{wjh12,mit-vax}!biomed!aoa!chuckles

Quantum Mechanics - "Where constants aren't, and variables de ae ae

brandon@tdi2.UUCP (Brandon Allbery) (05/23/87)

Quoted from <1994@a.cs.okstate.edu> ["Re: Shutting lint up about malloc (missing /*NOSTRICT*/)"], by gregg@a.cs.okstate.edu (Gregg Wonderly)...
+---------------
| in article <61@amanue.UUCP>, jr@amanue.UUCP (Jim Rosenberg) says:
| > 
| > This is driving me nuts.  I can't get lint on my system to shut up about
| > malloc.  In response to the following code:
| > 
|    ......
| > 
| >   /*NOSTRICT*/
| >   if ((p = (struct foo*) malloc(sizeof(struct foo))) == NULL) {
| >       (void) fprintf(stderr, "Out er memory, turkey\n");
| >       return NULL;
| >   }
+---------------

Even with the proposed change (casting NULL) lint -p will still yell about
casting malloc()'s result.  The document (NOT man page) for lint mentions
a -c option to silence this here, but /usr/bin/lint (which is a shell script)
contains a comment to the effect that lint -c is obsolete and unused.  (This
is System V Release 2, and actually lint -c produces .ln files.)

++Brando
-- 
Brandon S. Allbery	           UUCP: cbatt!cwruecmp!ncoast!tdi2!brandon
Tridelta Industries, Inc.         CSNET: ncoast!allbery@Case
7350 Corporate Blvd.	       INTERNET: ncoast!allbery%Case.CSNET@relay.CS.NET
Mentor, Ohio 44060		  PHONE: +1 216 255 1080 (home +1 216 974 9210)