Under Xcode 6.3, NULL C++ reference address evaluates as non-zero

492 views Asked by At

Similar to this question: XCode 6.3 Warning : Comparison of address of 'myObject' not equal to null pointer is always true

with C++, I found that previously working code for evaluating null pointers stopped working:

struct AStruct
{
    int x, y;
    char *name;
};

AStruct& GetStruct()
{
   return *(AStruct*)0;
}

int main(int argc, const char * argv[]) {

    AStruct& mys = GetStruct();

    if ( ! &mys) {
        printf("null pointer \n");
    }
    else
    {
        printf("NOT a null pointer\n");
    }

    return 0
}

This always prints out NOT a null pointer

I've tried other ways of pointer-to-reference checking:

if ( &mys == NULL)

if ( &mys == nullptr )

None of these worked.

Then I noticed the warning:

Reference cannot be bound to dereferenced null pointer in well-defined C++ code; comparison may be assumed to always evaluate to false

But there are no suggested fixes.

What is the canonical way of checking null pointers these days?

2

There are 2 answers

1
Jack On BEST ANSWER

You are not checking against a pointer, you are checking against a reference.

References are not supposed to be nullptr since they must refer to an existing value. Indeed what you are doing *(AStruct*)0 is not well defined since a reference shouldn't be able to generate undefined behaviour through "dereferencing it" but in this way you could trigger the problem.

If client code has a AStruct& then it can be sure that the reference points to something, you are breaking this condition.

If you need to work with references that can be null use a pointer, eg

AStruct* GetStruct()
{
  return nullptr;
}

if (!GetStruct())
{
  ...

The fact that the code worked in a previous version of Xcode is a symptom of the fact that this is not well-defined code.

2
Logicrat On

You don't have a pointer there; mys is a reference. Then when you check the value of &mys, you are checking the address of the reference.