Reference pointing to a Null-object

20,026

Solution 1

I was surprised that no one talked about when reference can point to a null object

That's because it can't, in a correct program.

Your function that dereferences a nullpointer has Undefined Behavior. The compiler is allowed to emit code that, for example, causes a crash at that point.

However, one possible effect of UB is that the code does what one thought it would do. So null-references can occur. I have never encountered one, but if you do, then it means that there is a serious logic error in the code.

All uses of the null-object-reference function you show, are logic errors.

You'd better grep up those uses and fix things. ;-)

Cheers & hth.,

Solution 2

I was surprised that no one talked about when reference can point to a null object.

Never.

(i) How is it possible to do *nullPtr - Is is it because nullPtr is a static object, which is allocated memory on the heap and hence it is guarenteed to have some space and address allocated for deref?

It's not. You're dereferencing a null pointer, which is invoking undefined behaviour.

(ii) Since we are returning const reference to obj, does compiler create a temporary object (to some kind of nullObj??) or Will the const reference act as an alias to nullPtr itself?

No. The compiler, at this stage, is allowed to produce nasal daemons or a black hole. If you're very lucky, you'll get a segmentation fault or some other kind of access violation.

DO NOT DO THIS

Share:
20,026
cppcoder
Author by

cppcoder

Updated on March 16, 2020

Comments

  • cppcoder
    cppcoder about 4 years

    I saw this discussion - Checking for a null object in C++ and I was surprised that no one talked about when reference can point to a null object. In our code, we use null objects routinely. There are functions as follows which return nullObj.

    const Obj&  
    nullObj()  
    {  
       static obj* nullPtr = NULL;   
       return static_cast<  const Obj&>(*nullPtr);    
    }  
    

    Actually, when I looked at the code again to bring this topic up, I had some questions on how the above code works:

    1. How is it possible to do *nullPtr - Is is it because nullPtr is a static object, which is allocated memory on the heap and hence it is guaranteed to have some space and

    2. Since we are returning const reference to obj, does compiler create a temporary object (to some kind of nullObj??) or Will the const reference act as an alias to nullPtr itself?

  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    Technically, it's the dereference that's undefined, not the reference.
  • littleadv
    littleadv almost 13 years
    @Tom, wasn't that what I said?:-)
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    You spoke more about when you try to access members through the reference, I think. But the point is that merely obtaining the reference is already undefined.
  • cppcoder
    cppcoder almost 13 years
    I understand - so obj& is reference to NULL pointer and there is no object created here. Does that mean nullPtr is never allocated any memory space?
  • cppcoder
    cppcoder almost 13 years
    does that mean reference to NULL pointer is invalid - even to use it symbolically? We always check the reference to see if it is not null and then use the reference only if reference is pointing to valid object.
  • cppcoder
    cppcoder almost 13 years
    Please look at this article on null object - citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.107.9051 (targeted at JAVA, UML). But the concept of null object seems valid - like unix uses /dev/null. the intent here was to provide an encapsulation for null object in c++, through reference to null pointer. But now I see that dereferencing nullPtr can lead to UB. Does c++ provide a better way to implement null objects?
  • littleadv
    littleadv almost 13 years
    @srikrish - what @Tom is trying to say that mere creating such a reference can lead to undefined behavior. He is correct per the C++ spec, although it is probably true that the "undefined behavior" will really kick in when you try to read/write to it, but you shouldn't relay on that because noone promises you that it will work, and if it will - won't get broken under a different compiler or compiler version. In short - you should never do what you're trying to do.
  • Lightness Races in Orbit
    Lightness Races in Orbit almost 13 years
    @srikrish: No, your obj& is a reference to an object that doesn't exist. You have a pointer that is a null pointer, which means that it does not point to a valid object. You're then trying to take a reference to this non-existent object. There is nothing wrong with the NULL pointer until you dereference it, because dereferencing a pointer that doesn't point to a valid object is, of course, undefined. You do not have a reference to a null pointer, which would be valid and look like this: T* ptr = NULL; T*& ref = ptr;
  • Cheers and hth. - Alf
    Cheers and hth. - Alf almost 13 years
    @sikrish: a C++ pointer can be null. That's one main reason to use pointers as arguments: that it supports null. A reference can't be null. And that's a main reason to use references as arguments: that they can't be null. Cheers & hth.,
  • Peter - Reinstate Monica
    Peter - Reinstate Monica about 6 years
    Funny, I encountered this construction in test code. A trivial template function almost like the OP's returns a reference for any type, always to the antinomy called a "null object". These references are used as constructor parameters for objects under test; the code paths for the specific test of course never reference that "null object". The rationale for not using pointers is exactly that in production code there is a guarantee that there is an object. Similar reasoning applies for not simply having default constructors. Terrible but convenient, and works in VS and our mid-90s compiler.
  • Don Hatch
    Don Hatch over 4 years
    @cppcoder to be perfectly clear: yes, the code is illegal, even if it doesn't access the object through it. @ littleadv - "probably true" is less and less meaningful these days: anything that a compiler is allowed to do, it will do, sooner or later. Agreed, just never do it.