Path: utzoo!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!brunix!sdm From: sdm@cs.brown.edu (Scott Meyers) Newsgroups: comp.lang.c++ Subject: Re: references to dereferenced null pointers Message-ID: <33209@brunix.UUCP> Date: 19 Mar 90 02:59:30 GMT References: <51083@microsoft.UUCP> <25EB8EE8.8462@paris.ics.uci.edu> <33188@brunix.UUCP> <10595@alice.UUCP> Sender: news@brunix.UUCP Reply-To: sdm@cs.brown.edu (Scott Meyers) Organization: Brown University Department of Computer Science Lines: 70 In article <10595@alice.UUCP> shopiro@alice.UUCP (Jonathan Shopiro) writes: >In article <33188@brunix.UUCP>, sdm@cs.brown.edu (Scott Meyers) writes: >> In article <10582@alice.UUCP> shopiro@alice.UUCP (Jonathan Shopiro) writes: >> > void h(int& r) >> > { >> > if (&r == 0) ... >> > } >> > >> > int* x = 0; >> > h(*x); >> >> Two comments: >> >> 1. In h(), r is a reference to an object. By definition, no object >> can have an address that is equal to 0, so (&r == 0) should always >> fail. >But the question is, must a reference actually refer to an object? Just as >a pointer can point to an object or to no-object, a reference could refer to >an object or to no-object. Then, if a reference referred to no-object, >(&r == 0) would succeed. Yes, a reference must actually refer to an object. (For the purposes of this discussion, variables of build-in types, e.g., int, are objects.) That's why references have to be initialized. Pointers are a different story entirely, because they don't have to be initialized. The only way to get a reference to no-object would be something like this: Object *ptr = 0; Object& ref = *ptr; But here again *ptr has to be evaluated to initialize ref. >> 2. In the call h(*x), we don't know precisely when *x is evaluated, >> but since r is initialized with that value, it must occur prior to >> executing any of the body of h(). >The real question is not _when_ is *x evaluated, but __how_. I claim that >*x is evaluated differently in > > int i = *x; // eval *x for rvalue > >than in > > int* p = &*x; // eval *x for lvalue > >and if x is the null pointer, the first is illegal and the second should >be legal, since x is never dereferenced. The call h(*x) is analogous >to the second example. I disagree; I think the question of "when is *x evaluated" is as real a question as there is. Perhaps what you really want is a new "operator&*" that has some kind of special semantics. After all, in the presence of a user-defined operator&, who says *x has to yield an lvalue in the expression &*x? Getting back to the original point of this discussion, I personally believe that it would be very convenient to have "null references," but I also believe that they don't exist and that making them exist would complicate a language that already has more than its share of complications. ("C++: The Programming Language Instructor's Full Employment Act.") Of course, I also tend to believe that references are an idea whose time should never have come. Maybe someone can enlighten me: what do references offer besides syntactic sugar? From my limited vantage point, they're just like pointers, but you can't new/delete them, you can't reassign them, and you can't compare them against 0. Don't get me wrong: I like sugar as much as anybody else, but syntactic sweetness has never been C++'s strong suit. In the case of references, I find that the confusion outweighs the convenience. Scott sdm@cs.brown.edu