Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!cis.ohio-state.edu!pacific.mps.ohio-state.edu!linac!att!pacbell.com!ames!mindcraft.com!karish From: karish@mindcraft.com (Chuck Karish) Newsgroups: comp.std.c Subject: Re: gcc and NULL function pointers. Message-ID: <678148665.20031@mindcraft.com> Date: 28 Jun 91 22:37:41 GMT References: <25572@well.sf.ca.us> <1146.Jun2221.20.2291@kramden.acf.nyu.edu> <16506@smoke.brl.mil> <17605.Jun2607.39.3591@kramden.acf.nyu.edu> <1991Jun27.190107.627@cirrus.com> Organization: Mindcraft, Inc. Lines: 48 In article <1991Jun27.190107.627@cirrus.com> dhesi@cirrus.com (Rahul Dhesi) writes: >In <17605.Jun2607.39.3591@kramden.acf.nyu.edu> >brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes: >>By the way, I'm curious: Why is ((char *)0) ``simply wrong''? > >It's wrong for the same reason that ((void *) 0) is wrong. K&R said >that NULL is defined to be 0. Not in my copy. They #defined NULL as 0 in an EXAMPLE. >Therefore existing code that (unwisely) >uses NULL to stand for a zero in a non-pointer context may break using >either ((void *) 0) or ((char *) 0). From K&R Classic, p. 192: The compilers currently allow a pointer to be assigned to an integer, an integer to a pointer, and a pointer to a pointer of another type. The assignment is a pure copy operation, with no conversion. This usage is nonportable, and may produce pointers which cause addressing exceptions when used. However, it is guaranteed that assignment odf the constant 0 to a pointer will produce a null pointer distinguishable from a pointer to any object. I don't see how anyone could read this as prohibiting implementations from defining NULL to be a pointer. It does suggest that pointers of different types may not be universally inter-assignable without careful type casting. >However, ((void *) 0) is blessed by ANSI and ((char *) 0) is not. >Therefore we may summarize: > > ((void *) 0) is ANSI-conformant but wrong. It does not allow maximal portability of sloppily-written (minimalist?) code (see K&R's warning, above), but it's not wrong. To answer Dan's question, ((char *)0) is wrong because the universally-castable storage type is (void *) under Standard C, not (char *). That's why malloc() now returns (void *). -- Chuck Karish karish@mindcraft.com Mindcraft, Inc. (415) 323-9000