13

I have read from the Wikipedia that:

“References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.”

However, I don’t believe this because of following code, which compiles with no error:

class person
{
    public:
    virtual void setage() = 0;
};

int main()
{
    person *object = nullptr;
    person &object1 = *object;
}
Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Zia ur Rahman
  • 1,411
  • 4
  • 26
  • 43
  • 7
    The article should probably say: "Every reference in a well-formed program refers to an object." Dereferencing a null pointer is of course ill-formed. – GManNickG Jan 29 '10 at 21:08
  • I think what you meant was `person &object1=object;`, which will indeed give you a compiler error (mismatched types). – BlueRaja - Danny Pflughoeft Jan 29 '10 at 21:10
  • 10
    And let's not all forget our favorite story about null references: http://www.gotw.ca/conv/002.htm – GManNickG Jan 29 '10 at 21:12
  • @GMan: Dereferencing a null pointer does result in undefined behavior; undefined behavior does not, however, render a program ill-formed. – James McNellis Jan 29 '10 at 21:12
  • 1
    @James: Oops, you're right. Better would be "...reference in a well-defined program... is of course undefined."? – GManNickG Jan 29 '10 at 21:15
  • 2
    @GMan: That sounds better to me. And, I LOLed at the linked GOTW. "I cannot teach him; he is drawn to Undefined Behavior:" sadly, I've known people like that. – James McNellis Jan 29 '10 at 21:39
  • 4
    Of course, the program *is* ill-formed. Mostly because of the missing `int`. – avakar Jan 29 '10 at 22:07
  • 5
    Not again... another null-reference discussion... The standard explicitly states (8.3.2/4) 'a null reference cannot exist in a well-defined program' – David Rodríguez - dribeas Jan 29 '10 at 22:25
  • 1
    "References cannot be null" looks very nice in a textbook until you see your program crash when reading from some reference that came from a dereferenced pointer 10 methods up the chain. The idea of non-nullable references creates a false sense of security and just moves the problem away from the symptoms. – martinkunev May 30 '21 at 23:16

7 Answers7

22

In your code:

person *object=NULL;
person &object1=*object;

you dereference a NULL pointer, so you get undefined behaviour. And to answer your question, there is no such thing as a NULL reference.

And to address the other part of your question, just because a program compiles, there is no guarantee that it is correct or that it will work. C++ compilers are not required to even attempt to diagnose the kind of error your code contains.

14

Saying person &object1=*object is not the same thing as saying person &object1=NULL. Probably the compiler is just not smart enough to find out that you are dereferencing null pointer, but you'll get a runtime error anyway. So they are kind of true still ;)

Tomas Vana
  • 18,317
  • 9
  • 53
  • 64
  • Even if the compiler catches this case, there will always be other cases it cannot catch. If you pass the reference through several methods, you'll have the actual program explode very far from where you do the dereferencing in code. This is not just a theoretical concern, I've seen it in production. – martinkunev May 30 '21 at 22:59
4

You can have a null reference, not sure why anyone would say otherwise, it is a nasty side effect of some operations. You just can't create one directly.

  • 1
    I should not be surprised to see downvoting, I can always tell what will set off the stupid people of the planet who think they know everything yet know nothing. – Charles Eli Cheese Jan 29 '10 at 22:36
  • 5
    You can get NULL references *in practice*. Whenever one says, "you *can't* have NULL references", it should read *in a well-formed program*. Besides dereferencing NULL pointers, it might also be possible to create a reference, so that `&ref == NULL` by doing self-initialization: `int& ref = ref;` (the result could be anything, including NULL, I suppose). - I don't think there'd be anything wrong covering the pragmatic aspect of the problem, but your answer is vague, uninformative and argumentative ("despite what everybody says, [somewhat gibberish point here]"). – UncleBens Jan 29 '10 at 22:50
  • 1
    @UncleBens, *Null* reference has connotations that aren't supported by the language. I think *invalid* reference better describes the situation. It's a subtle difference but I think it's less controversial. – Mark Ransom Jul 31 '12 at 23:12
3

that would crash your program. Did you try running it? doing *object will deference a null pointer, so in fact your reference never gets assigned.

Chris H
  • 6,433
  • 5
  • 33
  • 51
  • exelent answer i understood it. – Zia ur Rahman Jan 29 '10 at 21:03
  • 1
    I don't think it'll crash. It would crash only if you attempt to access members (or methods) of object1. – Julio Jan 29 '10 at 21:30
  • 3
    It might crash, print 42 or emit blue smoke - simply derefencing a null pointer invokes undefined behaviour so you can't know in advance. – Georg Fritzsche Jan 29 '10 at 21:36
  • 2
    Just tried with GCC. I created a "NULL reference" to string without a word from the compiler. Received a segmentation fault with GDB only when trying to call a member function. IMO, while you technically "can't have" NULL references, it is important to be aware of the issues when things don't go right. - In any case, the answer is wrong. If the behavior of something is undefined, *there is no guarantee that it will crash*. – UncleBens Jan 29 '10 at 23:17
2

Well, you can do whatever you want in C++. Another example:

person &object1 = *( reinterpret_cast<person*>(0) );

You are invoking an undefined behavior in the above case, beside the case you mentioned!

Khaled Alshaya
  • 94,250
  • 39
  • 176
  • 234
1

clang 3.5 even warns on a possible later NULL check of a reference:

/tmp/person.C:11:6: warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to
      always convert to true [-Wundefined-bool-conversion]
if (&object1) {}
~~   ^~~~~~~
1 warning generated.
Jan Kratochvil
  • 387
  • 3
  • 11
0

gcc8 will give a warning about it:

warning: the compiler can assume that the address of 'object1' will never be NULL [-Waddress]

A small demo:

#include <iostream>

class person
{
    public:
        virtual void setage()=0;
};

int main()
{
    person *object=NULL;
    person &object1=*object;

    if (&object1 == NULL) {
        std::cout << "NULL object1" << std::endl;
    }

    if (!(&object1)) {
        std::cout << "NULL object1 " << std::endl;
    }
}

Compile and running output:

g++ -std=c++2a -pthread -fgnu-tm -O2 -Wall -Wextra -pedantic -pthread -pedantic-errors main.cpp -lm -latomic -lstdc++fs && ./a.out

main.cpp: In function 'int main()':

main.cpp:14:18: warning: the compiler can assume that the address of 'object1' will never be NULL [-Waddress]

 if (&object1 == NULL) {

              ^

main.cpp:18:19: warning: the compiler can assume that the address of 'object1' will never be NULL [-Waddress]

 if (!(&object1)) {

               ^

NULL object1

NULL object1

leiyc
  • 903
  • 11
  • 23