[net.unix] if

allbery@ncoast.UUCP (Brandon Allbery) (09/06/86)

Quoted from <1170@ttrdc.UUCP> ["Re: strdup"], by levy@ttrdc.UUCP (Daniel R. Levy)...
+---------------
| In article <241@bsdpkh.UUCP>, heff@bsdpkh.UUCP (Paul K Heffner) writes:
| 
| >> /* hjb 08/25/86 */
| >> char * strdup(s)
| >> char *s;
| >> {
| >> 	char *p;
| >> 	extern char *malloc();
| >> 	if(p=malloc(strlen(s)+1)) strcpy(p,s);
| >> 	return p;
| >> }
| 
| >The above code doesn't return a null if malloc fails
| 
| It DOESN'T???  Gee, then maybe you have a busted malloc().  If malloc()
| fails, it should return the null pointer.  That is what is being tested in
| the clause 'if(p=malloc(strlen(s)+1))'.  As so many people have expounded
| in net.lang.c:  a null pointer is semantically the same as zero in the C
| language (except for sizeof(), should pointers exist of sizes other than
| sizeof(int)).
+---------------

But if a pointer is 4 bits and an int is 2 bits (some 68000 implementations),
you'll get spurious failures if the pointer returned by malloc is a multiple
of 0x10000!

++Brandon
-- 
  ---------------- /--/	Brandon S. Allbery		UUCP: decvax!cwruecmp!
 /              / /|\/	Tridelta Industries, Inc.        ncoast!tdi2!brandon
----    -------- /-++	7350 Corporate Blvd.		PHONE: +1 216 974 9210
   /   / /---,  ----	Mentor, Ohio 44060		SYSOP: UNaXcess/ncoast
  /   / /    / /  /	     -- HOME --			 (216) 781-6201 24 hrs.
 /   / /    / /  /	6615 Center St. Apt. A1-105	ARPA:  ncoast!allbery%
----  -----~ ----	Mentor, Ohio 44060-4101		 case.CSNET@csnet-relay

guy@sun.UUCP (09/08/86)

(This discussion has ceased to be related to UNIX; it is now a discussion of
C, so it is being moved to net.lang.c.)

> > It DOESN'T???  Gee, then maybe you have a busted malloc().  If malloc()
> > fails, it should return the null pointer.  That is what is being tested in
> > the clause 'if(p=malloc(strlen(s)+1))'.  As so many people have expounded
> > in net.lang.c:  a null pointer is semantically the same as zero in the C
> > language (except for sizeof(), should pointers exist of sizes other than
> > sizeof(int)).

> But if a pointer is 4 bits and an int is 2 bits (some 68000
> implementations), you'll get spurious failures if the pointer returned by
> malloc is a multiple of 0x10000!

Not if you've declared "malloc" to return a "char *", you won't.  All C
compilers will generate equivalent code for

	extern char *malloc();
	char *p;
	unsigned int i;

	if (p = malloc(i))
		foo();

and

	extern char *malloc();
	char *p;
	unsigned int i;

	if ((p = malloc(i)) != 0)
		foo();

Any compiler that does *not* generate equivalent code in these two cases is
not a C compiler; it compiles some other language that may look like C in
some ways, but is not C.  If it was intended to be a C compiler, it has a
bug.  (Any compiler that does not generate equally efficient code for these
two constructs is *also* broken, since they both mean the same thing in C.)

If you haven't declared "malloc" to return a "char *", this code will rarely
if ever work on a machine where "char *" and "int" have different sizes,
regardless of whether "malloc" succeeds or fails.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

chris@umcp-cs.UUCP (Chris Torek) (09/08/86)

In article <1427@ncoast.UUCP> allbery@ncoast.UUCP (Brandon Allbery) writes:
[re the following (edited) code:]
char *strdup(s) char *s; {
	char *p, *malloc();
	if(p=malloc(strlen(s)+1)) strcpy(p,s);
	return p;
}

>But if a pointer is 4 bits [sic] and an int is 2 bits (some 68000
>implementations), you'll get spurious failures if the pointer returned
>by malloc is a multiple of 0x10000!

No:  the test `if (p)' compares p with zero, and in this context
the zero is coerced to a (char *)0.  That the zero is only implied
is unimportant.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

lcc.jbrown@LOCUS.UCLA.EDU (Jordan Brown) (09/09/86)

> From: Brandon Allbery <allbery%ncoast.uucp@BRL.ARPA>
> [ code which used "if(pointer) stmt;" ]

> But if a pointer is 4 bits and an int is 2 bits (some 68000 implementations),
> you'll get spurious failures if the pointer returned by malloc is a multiple
> of 0x10000!

Those are the smallest pointers and ints I've ever seen!  But seriously,
K&R never says that the expression in an if is converted to an int.
It says (pg 201)
	...the expression is evaluated and it if is non-zero...
While this does not explicitly allow the if(pointer) usage, it can easily
be interpreted to mean that "if(expr)" is equivalent to "if(expr!=0)", which
IS guaranteed to work for pointers (pg 190).

Lots of code would break if this usage was not allowed.