1

As we all know there are no null references.
So I try to compile this line of code

int main{
    int &surprise_reference=*(int*)0;  
    return 0;}  

To my surprise this code works without a single warning .
Then I change my code to

int  main()   {
 int&suprise_reference=*(int*)0;  
 if(&suprise_reference==0)  
 std::cout<<"you don't know references";  
          return  0;
}

Output of program is you don't know references.
Does it mean that dereferencing a null pointer can lead to null references also?
Please help..

T.J.
  • 1,466
  • 3
  • 19
  • 35

3 Answers3

4

You can have a reference that ends up pointing at NULL. It's the result of undefined behaviors escaping the compiler's analysis. One trivial example of this would be a program that fills the entire heap, including the address where a reference is stored, with zeroes. Obviously if you did this, the reference would then point to memory address zero.

The C++ standard prohibits creating a reference to a NULL type, not a reference ever becoming NULL. And all type safety is only enforced where the compiler is able to reason about the types in question - using a hard C-style cast severely impedes that ability.

Borealid
  • 95,191
  • 9
  • 106
  • 122
3

What your experiment shows is that it happens to work on your particular computer. That doesn't mean it's "ok".

In particular, this line:

int &surprise_reference=*(int*)0;

is invalid C++ code, because (exactly as you said) a reference is not allowed to point to a NULL pointer. The result of doing something that's not allowed by the C++ standard is undefined behavior. In this particular case, on your particular computer, the undefined behavior happens to be pretty benign, but that doesn't make it predictable, or always OK.

See https://isocpp.org/wiki/faq/references#refs-vs-ptrs for more details. One thing that they point out in particular is that, because the compiler knows that creating a null reference is illegal, it may assume that you haven't done it -- for instance, if you have a function that takes p as a parameter, and you write

int &q = *(int*)p;
if (p == NULL)
  ...

it may conclude from the reference creation that p is known to be non-NULL, and optimize away the check. Then, if you pass in a NULL pointer for p, things may go badly wrong.

(That sort of assumption-and-optimization, by the way, is how a lot of the bad things from undefined code happen.)

seaotternerd
  • 6,298
  • 2
  • 47
  • 58
Brooks Moses
  • 9,267
  • 2
  • 33
  • 57
  • 2
    Clarification: In "knows that this is illegal", the "this" is referring to the general action of creating a `NULL` reference, not this particular piece of code. Most modern compilers don't check to see if the constant zero is being cast to a pointer type and flag the pointer so created as being `NULL` when that happens. Thus, `(int*)0` creates a generic `int*` which is treated like any other pointer-to-`int`. – Borealid Feb 04 '12 at 06:18
  • @Borealid: Thanks for the clarification! I've made the relevant edit in the answer. – Brooks Moses Feb 04 '12 at 19:11
1

Fix the bugs in the code and the mysteries will go away. Yes, code with bugs in it does strange things. That shouldn't be surprising and doesn't have any deep significance.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278