How do we check if a pointer is NULL pointer?

CNull Pointer

C Problem Overview


I always think simply if(p != NULL){..} will do the job. But after reading this Stack Overflow question, it seems not.

So what's the canonical way to check for NULL pointers after absorbing all discussion in that question which says NULL pointers can have non-zero value?

C Solutions


Solution 1 - C

> I always think simply if(p != > NULL){..} will do the job.

It will.

Solution 2 - C

First, to be 100% clear, there is no difference between C and C++ here. And second, the Stack Overflow question you cite doesn't talk about null pointers; it introduces invalid pointers; pointers which, at least as far as the standard is concerned, cause undefined behavior just by trying to compare them. There is no way to test in general whether a pointer is valid.

In the end, there are three widespread ways to check for a null pointer:

if ( p != NULL ) ...

if ( p != 0 ) ...

if ( p ) ...

All work, regardless of the representation of a null pointer on the machine. And all, in some way or another, are misleading; which one you choose is a question of choosing the least bad. Formally, the first two are indentical for the compiler; the constant NULL or 0 is converted to a null pointer of the type of p, and the results of the conversion are compared to p. Regardless of the representation of a null pointer.

The third is slightly different: p is implicitly converted to bool. But the implicit conversion is defined as the results of p != 0, so you end up with the same thing. (Which means that there's really no valid argument for using the third style—it obfuscates with an implicit conversion, without any offsetting benefit.)

Which one of the first two you prefer is largely a matter of style, perhaps partially dictated by your programming style elsewhere: depending on the idiom involved, one of the lies will be more bothersome than the other. If it were only a question of comparison, I think most people would favor NULL, but in something like f( NULL ), the overload which will be chosen is f( int ), and not an overload with a pointer. Similarly, if f is a function template, f( NULL ) will instantiate the template on int. (Of course, some compilers, like g++, will generate a warning if NULL is used in a non-pointer context; if you use g++, you really should use NULL.)

In C++11, of course, the preferred idiom is:

if ( p != nullptr ) ...

, which avoids most of the problems with the other solutions. (But it is not C-compatible:-).)

Solution 3 - C

The compiler must provide a consistent type system, and provide a set of standard conversions. Neither the integer value 0 nor the NULL pointer need to be represented by all-zero bits, but the compiler must take care of converting the "0" token in the input file to the correct representation for integer zero, and the cast to pointer type must convert from integer to pointer representation.

The implication of this is that

void *p;
memset(&p, 0, sizeof p);
if(p) { ... }

is not guaranteed to behave the same on all target systems, as you are making an assumption about the bit pattern here.

As an example, I have an embedded platform that has no memory protection, and keeps the interrupt vectors at address 0, so by convention, integers and pointers are XORed with 0x2000000 when converted, which leaves (void *)0 pointing at an address that generates a bus error when dereferenced, however testing the pointer with an if statement will return it to integer representation first, which is then all-zeros.

Solution 4 - C

The actual representation of a null pointer is irrelevant here. An integer literal with value zero (including 0 and any valid definition of NULL) can be converted to any pointer type, giving a null pointer, whatever the actual representation. So p != NULL, p != 0 and p are all valid tests for a non-null pointer.

You might run into problems with non-zero representations of the null pointer if you wrote something twisted like p != reinterpret_cast<void*>(0), so don't do that.

Although I've just noticed that your question is tagged C as well as C++. My answer refers to C++, and other languages may be different. Which language are you using?

Solution 5 - C

Apparently the thread you refer is about C++.

In C your snippet will always work. I like the simpler if (p) { /* ... */ }.

Solution 6 - C

The representation of pointers is irrelevant to comparing them, since all comparisons in C take place as values not representations. The only way to compare the representation would be something hideous like:

static const char ptr_rep[sizeof ptr] = { 0 };
if (!memcmp(&ptr, ptr_rep, sizeof ptr)) ...

Solution 7 - C

Well, this question was asked and answered way back in 2011, but there is nullptrin C++11. That's all I'm using currently.

You can read more from Stack Overflow and also from this article.

Solution 8 - C

if(p != NULL) is a safe and portable way to check if a pointer is NULL.

Section 7.19 of the C11 standard describes definitions contained in stddef.h, including NULL. The relevant parts are as follows:

> 1 The header <stddef.h> defines the following macros and declares the following types. Some are also defined in other headers, as noted > in their respective subclauses. > > ... > > 3 The macros are > > NULL > > which expands to an implementation-defined null pointer constant; ...

This only states that NULL is implementation defined. It doesn't say that it has to have all bits 0.

Also, section 6.2.3.2p3 defines null pointers and null pointer constants:

> An integer constant expression with the value 0, or such an > expression cast to type void *, is called a null pointer > constant. If a null pointer constant is converted to a pointer type, > the resulting pointer, called a null pointer, is guaranteed to > compare unequal to a pointer to any object or function.

While the above states that both 0 (when converted to a pointer) and (void *)0 constitute a null pointer constant, it doesn't imply that the resulting pointer has all bits 0. There are several other examples in the standard where converting a value from one type to another doesn't necessarily means the representation is the same.

This also states that a null pointer constant will compare unequal to any object or function. Paragraph 4 of this section also states:

> Conversion of a null pointer to another pointer type yields a null pointer of that type. Any two null pointers shall compare equal.

So that if p is a null pointer then it must compare equal to any null pointer including NULL, in which case p != NULL would evaluate to false. Conversely, if p points to an object or function then it must compare unequal to any null pointer in which case p != NULL would evaluate to true.

Again, note that nothing here makes any assumptions about what representation a null pointer would have.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncpuerView Question on Stackoverflow
Solution 1 - CcnicutarView Answer on Stackoverflow
Solution 2 - CJames KanzeView Answer on Stackoverflow
Solution 3 - CSimon RichterView Answer on Stackoverflow
Solution 4 - CMike SeymourView Answer on Stackoverflow
Solution 5 - CpmgView Answer on Stackoverflow
Solution 6 - CR.. GitHub STOP HELPING ICEView Answer on Stackoverflow
Solution 7 - CJohnJohnView Answer on Stackoverflow
Solution 8 - CdbushView Answer on Stackoverflow