7

Lets say you have something like this:

int& refint;
int* foo =0;
refint = *foo;

How could you verify if the reference is NULL to avoid a crash?

Andriy
  • 2,767
  • 2
  • 21
  • 29
jmasterx
  • 52,639
  • 96
  • 311
  • 557
  • 8
    You drag the developer who wrote that into a dark room with one chair and one light shining on it. Then you burn them with cigarettes until they repent. – Edward Strange Nov 24 '10 at 20:06

7 Answers7

11

You can't late-initialize a reference like that. It has to be initialized when it's declared.

On Visual C++ I get

error C2530: 'refint' : references must be initialized

with your code.

If you 'fix' the code, the crash (strictly, undefined behaviour) happens at reference usage time in VC++ v10.

int* foo = 0;
int& refint(*foo);
int i(refint);  // access violation here

The way to make this safe is to check the pointer at reference initialization or assignment time.

int* foo =0;
if (foo)
{
  int& refint(*foo);
  int i(refint);
}

though that still does not guarantee foo points to usable memory, nor that it remains so while the reference is in scope.

Steve Townsend
  • 53,498
  • 9
  • 91
  • 140
5

You don't, by the time you have a "null" reference you already have undefined behaviour. You should always check whether a pointer is null before trying to form a reference by dereferencing the pointer.

(Your code is illegal; you can't create an uninitialized reference and try and bind it by assigning it; you can only bind it during initialization.)

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
4

In general, you can't.

Whoever "creates a null reference" (or tries to, I should say) has already invoked undefined behavior, so the code might (or might not) crash before you get a chance to check anything.

Whoever created the reference should have done:

int *foo = 0;
if (foo) {
    int &refint = *foo;
    ... use refint for something ...
}

Normally it's considered the caller's problem if they've written *foo when foo is null, and it's not one function's responsibility to check for that kind of error in the code of other functions. But you could litter things like assert(&refint); through your code. They might help catch errors made by your callers, since after all for any function you write there's a reasonable chance the caller is yourself.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
1

All the answers above are correct, but if for some reason you want to do this I thought at least one person should provide an answer. I am currently trying to track down a bad reference in some source code and it would be useful to see if someone has deleted this reference and set it to null at some point. Hopefully this wont generate to many down votes.

    #include <iostream>
    int main()
    {
        int* foo = nullptr;
        int& refint = *foo;

        if(&refint == nullptr)
            std::cout << "Null" << std::endl;
        else
            std::cout << "Value " << refint << std::endl;
    }

Output:

Null

marsh
  • 2,592
  • 5
  • 29
  • 53
  • Note: output is Null in this case because int *foo; just happened to be nullptr. Since it is uninitialized it could be anything. I would initialize it to nullptr. – Mr. Developerdude Nov 19 '16 at 00:06
0

To make the above code compile, you will have to switch the order:

int* foo =0;
int& refint = *foo; // on actual PCs, this code will crash here 

(There may be older processor or runtime architectures where this worked.)

Doc Brown
  • 19,739
  • 7
  • 52
  • 88
0

....saying all of the above, if you do want to have a null reference, use boost::optional<>, works like a charm..

Nim
  • 33,299
  • 2
  • 62
  • 101
-5

You don't need to, references cannot be null.

Read the manual.

Alex Brown
  • 41,819
  • 10
  • 94
  • 108