Path: utzoo!attcan!sobmips!uunet!mcsun!hp4nl!star.cs.vu.nl!keie From: keie@cs.vu.nl (Ed Keizer) Newsgroups: comp.os.minix Subject: NULL Keywords: C null pointer Message-ID: <4555@math.cs.vu.nl> Date: 16 Nov 89 12:20:13 GMT Organization: V.U. Informatica, Amsterdam, the Netherlands Lines: 105 I would like to add the following opinions to the current debate on NULL pointer constants. The context I use the current, and probably final, version of the proposed ANSI C standard. 1 - It is up to the creator of a C implementation whether the NULL pointer constant is defined as one of 0 0L (void *) 0 One might even define NULL as `5-5', as that is a constant expression with the value 0. I added a part section 3.2.2.3 of the december 1988 version of the pANS C standard that clearly states this. 2 - Thus it is a question of taste and convenience which form to choose. Taste is hard to measure, but convenience is a usable criterium. It follows from this criterium that an implementor should try to avoid pitfalls for the unwary. The pitfalls in the use of the null pointer constant lie in the passing of null pointers to routines without prototypes. In all other places the implementation can cast NULL to the appropiate type. `0' or `0L' passed as an argument may have a different representation from null pointers. Therefore it is wise to define NULL as `(void *)0'. The problem is less severe in Standard C because all library routines have prototypes there. I have added a few paragraphs from the Rationale accompanying the proposed C standard for further elucidation. 3- Chris Torek's argument for `0' instead of any other form is a invalid. Basicly his, and others people's, solution to the problem of null pointers with different representations for different types is to always cast NULL to the proper type. This solution will work for ALL definitions of NULL allowed by the C standard. And thus offers NO argument contra or pro NULL defined as `0'. 4- The opinion of Henry Spencer that a cast of 0 to any other pointer type than `void *' is illegal and pointless, is incorrect. It is not illegal, it is implementation defined and non-portable. I would be very surprised though to see an implementation that produces different result for the expressions `(char *)(void *)0' and `(char *)0'. I fully agree with Henry Spencer's opinion that all this is a concession to badly written code. 5- I disagree with Diomidis Spinellis's opinion a C implementor should go to lengths to punish people for writing bad code. On the contrary, it is in the `Spirit of C' to not break existing code. A user should be warned against non-portable code by an implementation, but not punished harshly. Finally, which definition of NULL to choose is definitely up to the creator of a C implementation. Programs should simply use NULL, and never define it. If a C implementation behaves with (void *) as specified in the ANSI standard that implementor would be wise to define NULL as `(void *)0'. I do not express any opinions on the wisest choice for NULL on C implementations that do not conform to the proposed C standard. Some extracts: Proposed C standard: paragraph 3.2.2.3, page 38 An integral constant expression with the value 0, or such an expression cast to type `void *', is called a `null pointer constant'. If a null pointer constant is assigned to or compared for equality to a pointer, the constant is converted to a pointer of that type. Such a pointer, called a `null pointer', is guaranteed to compare unequal to a pointer to any object or function. Rationale paragraph 3.3.9, page 47 In pointer comparisons, one of the operands may be of type `void *'. In particular, this allows NULL, which can be defined as `(void~*)0', to be compared to any object pointer. Rationale paragraph 4.1.5, page 73 NULL can be defined as any null pointer constant. Thus existing code can retain definitions of NULL as 0 or 0L, but an implementation may choose to define it as `(void~*)0'; this latter form of definition is convenient on architectures where the pointer size(s) do(es) not equal the size of any integer type. It has never been wise to use NULL in place of an arbitrary pointer as a function argument, however, since pointers to different types need not be the same size. The library avoids this problem by providing special macros for the arguments to signal, the one library function that might see a null function pointer. Ed Keizer Vrije Universiteit Amsterdam Member of ISO/IEC JTC1/SC22/WG14-C The opinions stated here are mine and not those of WG14.