Do You Use Null or 0 (Zero) For Pointers in C++

Do you use NULL or 0 (zero) for pointers in C++?

Here's Stroustrup's take on this: C++ Style and Technique FAQ

In C++, the definition of NULL is 0, so there is only an aesthetic difference. I prefer to avoid macros, so I use 0. Another problem with NULL is that people sometimes mistakenly believe that it is different from 0 and/or not an integer. In pre-standard code, NULL was/is sometimes defined to something unsuitable and therefore had/has to be avoided. That's less common these days.

If you have to name the null pointer, call it nullptr; that's what it's called in C++11. Then, nullptr will be a keyword.

That said, don't sweat the small stuff.

NULL vs Zero in C

From this NULL pointer reference:

To initialize a pointer to null or to assign the null value to an existing pointer, a null pointer constant (NULL, or any other integer constant with the value zero) may be used.

[Emphasis mine]

So the integer constant 0 is a valid null pointer constant.

But note that it doesn't mean that the actual null value on the hardware platform used is equal to 0, it only means that the compiler accepts 0 as an alias for the system-dependent null pointer constant.

Also, a null pointer is always "false" and a non-null pointer is always "true", which is why a condition like if (ptr) or if (!ptr) works well.

When to use NULL and when to use '\0' in linked list in C?

This is a very common confusion. A "null character" (often spelled NUL, with only one L, for historical reasons) is a character that compares equal to zero. A "null pointer" is a pointer that compares equal to zero. The difference is only the type -- but that is an important difference. The compiler is allowed, but not required, to object to your program, because you are comparing a character value to a null pointer constant.

C has a fairly loose type system, especially when it comes to integer constants, so you can get away with using constants with a formally incorrect type a lot of the time. This is especially true when it comes to zero: the integer literal 0 can be used everywhere it is safe to use the macro NULL or the character literal '\0'. In fact, the implementation is specifically allowed to use #define NULL 0 in all editions of the C standard. Because of this, there are a small handful of contexts where one absolutely must use (T*)0 for some concrete type T, instead of either bare 0 or NULL, such as when passing null pointers to a function that takes a variable number of arguments (e.g. execl).

As further icing on the confusion cake, in C character literals have type int, not char, and '\0' is a legitimate null pointer constant. (In C++ neither of those things is true.)

Best practice in C, IMNSHO, is to use '\0' for the null character, and 0not NULL — for the null pointer.

Is NULL always zero in C?

I'm assuming you mean the null pointer. It is guaranteed to compare equal to 0.1 But it doesn't have to be represented with all-zero bits.2

See also the comp.lang.c FAQ on null pointers.


  1. See C99, 6.3.2.3.
  2. There's no explicit claim; but see the footnote for C99, 7.20.3 (thanks to @birryree in the comments).

Whats better to use in C++11 , Zero or NULL?

The other answers are right. But I wanted to say a little more about why nullptr is better.

In C++11 "perfect forwarding" is very important. It is used everywhere. Obvious places are bind and function. But it is also used in a multitude of other places under the covers. But "perfect forwarding" isn't perfect. And one of the places it fails is null pointer constants.

template <class T>
void display(T)
{
std::cout << type_name<T>() << '\n';
}

template <class T>
void
f(T&& t)
{
display(std::forward<T>(t)); // "perfectly forward" T
}

int main()
{
f(0);
f(NULL);
f(nullptr);
}

With an appropriate definition of type_name<T>(), on my system this prints out:

int
long
std::nullptr_t

This can easily make the difference between working code and errors. With any luck your errors will come at compile time (with horrible error messages). But you may also get run time errors in some circumstances.

Aggressively ban use of 0 and NULL in your code.

Even if you're not perfect forwarding in your code, code you call (such as the std::lib) is very likely using it under the covers.

Is there any difference in comparing a pointer with 0 or with NULL?

The correct usage is to use NULL : It's more readable (p = NULL -> you know that p is a pointer)

How compiler handles a non-zero null pointer value in C?

if (!pointer)

If the C implementation used the value DEADBEEF16 for a null pointer, the compiler would compile if (!pointer) to code such as:

    compare             pointer, #0xDEADBEEF
branch-if-not-equal else-clause

if (pointer == 0)

An integer constant zero qualifies as a “null pointer constant” (C 2018 6.3.2.3 3). When a pointer is compared to a null pointer constant, the null pointer constant is converted to the type of the pointer (6.5.9 5). The compiler would implement this conversion by producing DEADBEEF16 for the resulting pointer. Then it would compare pointer to DEADBEEF16 and branch accordingly.

Simply put, just because the character “0” appears in source code does not mean the compiler has to use zero in the instructions it generates. It generates whatever instructions and values it needs to get the job done.

I am really unable to understand how this literal 0 becomes non-all-bits-zero when initialized to a pointer.

There is nothing about the character “0” that forces a compiler to give it a value of zero. The code for “0” is 48 in ASCII and 240 in EBCDIC, so the compiler is not starting with a value of zero when it processes this or other characters. Normally, when processing numerals, it has to read the digits and do some arithmetic to calculate the numbers represented by the numerals. It is that software that causes “0” to stand for the value zero or that causes “23” to stand for the value twenty-three. To make “0” represent a null pointer, the software in the compiler simply substitutes the internal value of a null pointer wherever “0” is used in a context for a pointer.

For example, in void *x = 0;, the compiler might initially convert “0” to zero, but this will be part of a data structure that also says this is a token or integer constant expression that currently has the value zero. When the compiler sees this integer constant expression is being used to initialize a pointer, it will change the value, and it will generate code that initializes the pointer to the internal value for a null pointer.

Can I use NULL as substitution for the value of 0?

Am I allowed to use the NULL pointer as replacement for the value of 0?

No, it is not safe to do so. NULL is a null-pointer constant, which could have type int, but which more typically has type void * (in C), or otherwise is not directly assignable to an int (in C++ >= 11). Both languages allow pointers to be converted to integers, but they do not provide for such conversions to be performed implicitly (though some compilers provide that as an extension). Moreover, although it is common for converting a null pointer to an integer to yield the value 0, the standard does not guarantee that. If you want a constant with type int and value 0 then spell it 0.

  • Am I might crossing into Undefined Behavior with this?

Yes, on any implementation where NULL expands to a value with type void * or any other not directly assignable to int. The standard does not define the behavior of your assignment on such an implementation, ergo its behavior is undefined.

  • is it permissible to operate with the NULL in that way?

It is poor style, and it will break on some systems and under some circumstances. Inasmuch as you appear to be using GCC, it would break in your own example if you compiled with the -Werror option.

  • Is there anything wrong about to use NULL as numerical value in arithmetical expressions?

Yes. It is not guaranteed to have a numerical value at all. If you mean 0 then write 0, which is not only well defined, but shorter and clearer.

  • And how is the result in C++ to that case?

The C++ language is stricter about conversions than is C and has different rules for NULL, but there, too, implementations may provide extensions. Again, if you mean 0 then that's what you should write.

What is the difference between NULL, '\0' and 0?

Note: This answer applies to the C language, not C++.



Null Pointers

The integer constant literal 0 has different meanings depending upon the context in which it's used. In all cases, it is still an integer constant with the value 0, it is just described in different ways.

If a pointer is being compared to the constant literal 0, then this is a check to see if the pointer is a null pointer. This 0 is then referred to as a null pointer constant. The C standard defines that 0 cast to the type void * is both a null pointer and a null pointer constant.

Additionally, to help readability, the macro NULL is provided in the header file stddef.h. Depending upon your compiler it might be possible to #undef NULL and redefine it to something wacky.

Therefore, here are some valid ways to check for a null pointer:

if (pointer == NULL)

NULL is defined to compare equal to a null pointer. It is implementation defined what the actual definition of NULL is, as long as it is a valid null pointer constant.

if (pointer == 0)

0 is another representation of the null pointer constant.

if (!pointer)

This if statement implicitly checks "is not 0", so we reverse that to mean "is 0".

The following are INVALID ways to check for a null pointer:

int mynull = 0;
<some code>
if (pointer == mynull)

To the compiler this is not a check for a null pointer, but an equality check on two variables. This might work if mynull never changes in the code and the compiler optimizations constant fold the 0 into the if statement, but this is not guaranteed and the compiler has to produce at least one diagnostic message (warning or error) according to the C Standard.

Note that the value of a null pointer in the C language does not matter on the underlying architecture. If the underlying architecture has a null pointer value defined as address 0xDEADBEEF, then it is up to the compiler to sort this mess out.

As such, even on this funny architecture, the following ways are still valid ways to check for a null pointer:

if (!pointer)
if (pointer == NULL)
if (pointer == 0)

The following are INVALID ways to check for a null pointer:

#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)

as these are seen by a compiler as normal comparisons.

Null Characters

'\0' is defined to be a null character - that is a character with all bits set to zero. '\0' is (like all character literals) an integer constant, in this case with the value zero. So '\0' is completely equivalent to an unadorned 0 integer constant - the only difference is in the intent that it conveys to a human reader ("I'm using this as a null character.").

'\0' has nothing to do with pointers. However, you may see something similar to this code:

if (!*char_pointer)

checks if the char pointer is pointing at a null character.

if (*char_pointer)

checks if the char pointer is pointing at a non-null character.

Don't get these confused with null pointers. Just because the bit representation is the same, and this allows for some convenient cross over cases, they are not really the same thing.

References

See Question 5.3 of the comp.lang.c FAQ for more.
See this pdf for the C standard. Check out sections 6.3.2.3 Pointers, paragraph 3.



Related Topics



Leave a reply



Submit