C++ Short circuit evaluation on pointers

Started by
7 comments, last by ToohrVyk 16 years, 8 months ago
Lets say I have a pointer to a playerobject and had to check if the pointer points at a memory address, and if it is, check if the object had been assigned a name or something: if(pPlayer != NULL && pPlayer->GetName().length() > 0) { cout << "You already have a character. Forfeit the old one?" << endl; cout << "(1) " << YES << endl; cout << "(2) " << NO << endl; /* take input, process it */ } If the pointer was a null pointer, it would be hazardous to call a method of it's object type, but since this is a short circuit, the second check will never happen unless pPlayer points to a real object, so this is in my oppinion not a dangerous move, but it's maybe a very bad design decision? What do you guys think?
Advertisement
It should be perfectly OK and sometimes a little conciseness is a good thing IMO.

Consider it an idiom like "safe dereferencing". You might omit the explicit comparison against NULL (it's 0 in C++ anyway :))

if (p && p->foo() )


If you need to do that a lot, your code might become too cluttered with checks on all lines anyway.

However, generally you might try to avoid a design where a pointer might end up being a 0-pointer. If possible make sure that the constructor initializes it properly. Also make sure that the constructor deletes it properly.

Sometimes functions, for example, might need to return 0-pointers though (if you don't want the exception mechanism), and the above would be OK.
Thanks for your answer, visitor. I'll convert to your way of checking. :)

In short, this is a very exceptional code in my program and is only used during the creation of a player object. But I don't think my implementation of it is a very good solution and I'm trying to refactor it a bit. :)
Quote:Original post by visitor
You might omit the explicit comparison against NULL (it's 0 in C++ anyway :))


This part of your post implies incorrect things—the explicit comparison against NULL can be omitted because that's the way pointer evaluation in boolean contexts works, not because the null pointer is zero.

The real facts in the matter are that when evaluated in a pointer context, the compile-time integer constant 0 is converted to a null pointer for the particular pointertype you're manipulating (though the memory representation of the null pointer may be completely different from that of the integer 0, and may differ from pointer to pointer) and when evaluated in a boolean context, a pointer is converted to false if and only if it's null, and true otherwise.

The rest of the post is correct.
Quote:
This part of your post implies incorrect things—the explicit comparison against NULL can be omitted because that's the way pointer evaluation in boolean contexts works, not because the null pointer is zero.


In C++ NULL is defined as 0. Now the actual memory address value may be anything but it is up to the compiler to ensure that for all practical purposes (from a programmer's - not a computer technicians viewpoint :)) a null pointer's value is 0.

For this reason you might do without the macro (included from a header), and simply use 0 instead of it.

int* p = 0; //initialized null pointer


Quote:
In C++ NULL is defined as 0.

Correct.

Quote:
a null pointer's value is 0.

Incorrect.

There is a very subtle difference here. In practice, currently on modern commodity desktop PCs, this may be true. That does not make it correct to assume so. The value of a null pointer is not specified by the C++ standard; what is specified is that the integral constant 0 is convertible to the appropriate value. This is possible because, despite many assumptions to the contrary in an obscene amount of code, the values of pointers are not integers.

By way of illustration, it is safe to assign 0 to a pointer. It is not safe to memset the value of that pointer to zero; that will not neccessarily produce a null pointer.
Quote:
Now the actual memory address value may be anything but it is up to the compiler to ensure that for all practical purposes (from a programmer's - not a computer technicians viewpoint :)) a null pointer's value is 0.


Nope. It is up to the programmer to ensure any pointer they wish to be "null" (and hence evaluate to false in a boolean context) is assigned the literal 0 (or NULL).
Sorry to argue in another person's thread but I feel that you are taking fragments of my posts out of context.

By null pointer, I mean a pointer that has been assigned a literal value 0.

These don't result in null pointers:
int* p; //uninitializeddelete p; //doesn't set p to 0


By practical purposes I meant initializing to 0 and testing for null-ness against the value 0.

I have to admit the point about memset is valid. Never occurred to me that you might do this kind of a monstrosity to a simple sad pointer :)

Another "non-practical purpose" that shouldn't be attempted is pointer arithmetics involving null pointers, but that falls under a different rule (pointer arithmetics gives reliable results only for pointers that point to the same type / array).
Quote:Original post by visitor
delete p; //may or may not null p 


Fixed [smile]

This topic is closed to new replies.

Advertisement