Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!ames!oliveb!apple!rutgers!att!ulysses!andante!alice!shopiro From: shopiro@alice.UUCP (Jonathan Shopiro) Newsgroups: comp.lang.c++ Subject: Re: Reference Semantics Summary: It's not always possible to check for zero references Message-ID: <9310@alice.UUCP> Date: 5 May 89 15:39:45 GMT References: <315@odi.ODI.COM> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 80 In article <315@odi.ODI.COM>, benson@odi.com (Benson Margulies) writes: > I've found a use for reference variables that refer via the null > pointer. In the starkest of terms, > > example& t = *(example *)0; > > I'd like to clarify the official language philosophy in this area, and > I hope to persuade the designers that this is a good use. > > Consider an interface like: > > gadget& find_a_gadget (char * gadget_name, int& error); > > What should this do if the named gadget cannot be found, and error > signalling out-of-line is undesirable? > > It seems natural to me for find_a_gadget to do the following: > > error = ENOGADGET; > return *(gadget *)0; > > So I would like to see the definition of the language state that it is > permissible to say: > > return *(type 0); You meant *(type*)0; > > in a function of type type&. Of course this more-or-less works in the current AT&T compiler, and I don't see any reason why it should not work in any other implementation (but the _only_ meaningful operation is to take the address of a zero-referenced object). However, I would recommend strongly against using this as a programming style. The problem is it's just too brittle. Suppose you had Type& f(); // a function that might return a zero reference Type t = f(); // note t is not a reference When f() decides to return a zero reference, the program will most likely crash, because the generated code will try to use the reference returned from f() to initialize t. In other words, the only way to safely use f() is Type& tr = f(); if (&tr != 0) { // use the referenced object } and all other uses of f() are unsafe. If you must return a reference to an object, you can encode the idea that this object is the result of a failed operation in its state, or (here's a gross hack for you) extern Type failedOperationInstanceOfType; Type& tr = f(); // f can return a reference to the above if (&tr != &failedOperationInstanceOfType) { // use the referenced object } At least in this case the program won't crash if you try to copy the failure object. > > As an additional suggestion, it occurs to me that the following might > be a good extension of the language: > > type& ref = initial_ref; > > &ref = new_reference; > > &foo on the LHS has no current semantics, so defining it to mean > rebind the reference conflicts with nothing. But then &ref as an lvalue would have a completely different meaning from &ref as an rvalue. Too confusing. -- Jonathan Shopiro AT&T Bell Laboratories, Warren, NJ 07060-0908 research!shopiro (201) 580-4229