Xref: utzoo comp.lang.c++:6799 comp.std.c:2602 Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!wuarchive!texbell!merch!sneaky!gordon From: gordon@sneaky.UUCP (Gordon Burditt) Newsgroups: comp.lang.c++,comp.std.c Subject: Re: references to dereferenced null pointers Message-ID: <29268@sneaky.UUCP> Date: 13 Mar 90 00:29:44 GMT References: <51083@microsoft.UUCP> <25EB8EE8.8462@paris.ics.uci.edu> <52081@microsoft.UUCP> <25F8D2FB.10981@paris.ics.uci.edu> <1990Mar11.015305.28264@utzoo.uucp> <1990Mar11.222634.2701@almira.uucp> Followup-To: comp.lang.c++ Organization: Gordon Burditt Lines: 94 Implementations in which the value of a null pointer is not zero are legal, but painful. > I beg to differ. I see where you are coming from with the wording: >"an integral constant expression with the value 0", but in K&R First edition, >page 97, there is an explicit example which 0 is returned by a function The example shows the integer constant 0 being returned from a function that returns a pointer to character. Fine. The compiler can convert it to: movl #0xdeadbee1,d0 rts at compile time. The compiler knows it has to convert 0 in a return statement to the type of the return type of the function. >returning a pointer to a character. Also, from the text "C guarantees that no >pointer that validly points at data will contain zero, so a return value of >zero can be used to signal an abnormal event,..." "contain 0": that combination of bits that results from executing: p = 0; commonly implemented by: movl #0xdeadbee1,_p > Also, from Appendix A, section 7.7 (Equality operators) "A pointer may be >compared to an integer, but the result is machine dependent unless the integer >is the constant 0. A pointer to which 0 has been assigned is guaranteed no to ^^^^^^^^^^ >point to any object, and will appear to be equal to 0; in conventional usage, "appear to be equal to zero" means p == 0 is true, not something involving peeking at bits in a machine register. >such a pointer is considered to be null." This implies to me that I can >compare a pointer to any arbitrary expression which evaluates to 0 and have It sure doesn't imply that to me. The zero being discussed is constant 0, not an int variable containing 0. The comparison p == 0 (to yield a "boolean" value, not a branch) might be translated as: cmpl #0xdeadbee1,_p jeq .L5001 movl #0,d0 jmp .L5002 .L5001: movl #1,d0 .L5002: Slow, yes. But a perfectly legal implementation. >machine independent behavior. And from section 7.14, "it is guaranteed that >the assignment of the constant 0 to a pointer will produce a null pointer ^^^^^^^^^^ >distinguishable from a pointer to any object." Since the "BNF" for this >section lists "lvalue = expression," I would assume that if expression >evaluates to 0 then the pointer will produce a null pointer distinguishable >from a pointer to any object. Where do you get that assumption? It is legal to assign an integer expression to a pointer, but that doesn't make it machine-independent. The BNF certainly doesn't say anything explicitly about the machine-dependent characteristics of addition with overflow, division by zero, or shifts by negative amounts, so why should it be expected to say something in this case? Just before the section you quoted, it says, "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 unportable, and may produce pointers which cause addressing exceptions when used." Since "an integer variable containing zero" does not fit the exception for the integer constant zero, assigning one to a pointer IS unportable. > As far as ANSI C goes, I do not have easy access to the standard at the >current time, nor the experience reading it. However, I would have expected >this behavior to be brought forward (hopefully not a silly idea, but we'll >see). ANSI C seems quite careful NOT to require that the representation of a null pointer is all zero bits. > This was a quick scan through K&R, so I hope I have not taken anything >out of context. The only reason this objection stuck in my mind is that I had >once thought of doing an implementation where NULL != 0, but after further >reading convinced myself the implementation would be invalid. Don't confuse NULL and the bits used to represent a null pointer. NULL == 0 must be true. assembly_language_representation_of(NULL) == 0 need not be true. An implementation in which ((char *) NULL) == 0 and ((char *) NULL) == 0xdeadbee1 are both true is possible, provided that assembly-language address 0xdeadbee1 isn't a possible address for a variable. Gordon L. Burditt sneaky.lonestar.org!gordon