Search code examples
c++xcodepointersmemory-alignmenttype-safety

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


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?


Solution

  • 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.