Concepts / Pointer Basics in C++

Pointer Basics in C++

The source recommends using nullptr rather than 0 or NULL for the null pointer value.

  • Programming

A Pointer With Nothing to Point At

Sometimes a pointer has to exist before there is anything for it to point at. A program might declare a pointer now and assign its target later. Or it might need a way to say that a pointer currently refers to no object at all. C++ needs a value for that situation, and the value you write in your source code matters. Several different spellings have been used for it over the years, so a learner will quickly run into three of them: nullptr, 0, and NULL.

What do you think happens?

Before reading on, choose which of the three spellings you would write when a pointer must refer to no object, and why. Then consider what the short program below prints.

  • nullptr

  • 0

  • NULL

Reveal answer
Answer:

Use nullptr. The recommendation is to write nullptr rather than 0 or NULL, because its spelling states that a pointer is being set to the null pointer value.

The source states the recommendation directly. The rest of this article explains what it means in practice.

The question this article answers is simple: when you need to write the null pointer value, which spelling should you use? The source gives a single preference, and the sections below trace what happens to a pointer from creation to use so you can see why that preference matters.

Tracing a Pointer From Creation to Use

The clearest way to see the recommendation in use is to declare a pointer and give it the null value at the moment it is created. The example below is generated for teaching purposes. It declares an int pointer, initializes it to nullptr, checks it, and only then points it at a real object and checks again.

cpp
Output
p refers to no object
p refers to value 42
Notes on the code
  • int* p = nullptr; creates the pointer and gives it the explicit null pointer value at the moment of creation
  • p == nullptr compares the pointer to nullptr, so the test reads as plain English
  • p = &value; makes the pointer refer to a real object
  • p != nullptr checks the pointer again before the program uses *p
pnullptrpaddress of valuevalue42refers to
What does the pointer variable contain when it is initialized to nullptr, compared with when it refers to a real object?

In the before state, p holds the null pointer value and refers to no object. In the after state, the same variable p refers to value. The variable itself is the thing that changes. Its meaning is set by the value it holds, which is why a clear, explicit null value is useful from the very first line.

Three Spellings for the Null Value

All three spellings appear in older code and in discussions of pointers, which is why the recommendation exists. When you need to write the null pointer value, you will see nullptr, 0, and NULL. The source's single preference is nullptr. Each of the three plays a different role in how a reader interprets the line where it appears.

nullptrthe explicit null pointervalue0a plain number that readermust reinterpret as apointer valueNULLolder spelling seen inexisting code
How do nullptr, 0, and NULL differ in the role each plays, and which one states the null pointer value directly?
SpellingWhat it looks like to a readerRole in pointer codeSource preference
nullptrA name that clearly says null pointerSets or tests a pointer for the null pointer valueRecommended
0A plain integer literalCan be used as a pointer value, but the reader must remember that it is not a plain number hereNot recommended
NULLA spelling found in older codeUsed in older code for the null pointer valueNot recommended

Each spelling's role as described in the source. The source gives one preference and does not compare them in further detail.

The difference is mostly about intent. When you write nullptr, the code states that a pointer is being set to the null pointer value. When you write 0 in the same position, the reader has to remember that 0 is being used as a pointer value and not as a plain number. The same holds for NULL. The recommendation asks you to choose the spelling that says what you mean.

Checking a Pointer Before Use

The source says to compare pointers against nullptr when checking whether they refer to an object. Think of the check as a decision the program makes before it uses the pointer. The flowchart below shows that sequence for a pointer p.

Pointer pdeclared and initializedp == nullptr?Do not use pno object to useUse *ppointer refers to an objectyesno
What sequence of decisions does a program make when it checks a pointer for nullptr before using it?
Worked example

Guarding a pointer that may be null

A function receives a pointer named p. Show how to write the check so the pointer is only used when it refers to an object.

  1. 1
    Compare the pointer to nullptr

    Write if (p == nullptr) so the test reads as a comparison against the explicit null pointer value.

  2. 2
    Handle the null case first

    Inside that branch, do not dereference p. Print a message or return instead, because there is no object to read.

  3. 3
    Use the pointer in the other case

    After the null case is handled, the program may use *p, since the pointer now refers to an object.

Result

The pointer is checked against nullptr before it is used, and the check reads clearly to anyone who opens the code.

Mixing 0, NULL, and nullptr

The main risk is not any one spelling. It is using several spellings in the same codebase. When 0, NULL, and nullptr all appear, a reader has to decide, line by line, which one is meant and whether each is being used as a pointer value.

  • Common mistake

    Initializing a pointer with 0 because it looks like a number that means nothing

    What it looks like
    int* p = 0;
    Why it fails

    The 0 is a pointer value here, but the reader has to remember that. The source recommends a spelling that states the intent directly.

    Do this instead
    int* p = nullptr;
  • Common mistake

    Mixing 0, NULL, and nullptr in the same codebase

    Why it fails

    Readers must decide which spelling is meant each time they see it, which makes the code harder to follow.

    Do this instead

    Pick nullptr and use it consistently for initialization and checks.

  • Common mistake

    Testing a pointer's value without comparing it to nullptr

    What it looks like
    if (p) { std::cout << *p; }
    Why it fails

    This example is generated for teaching purposes. It does not match the source's described habit of comparing against nullptr, so the intent is less explicit for a learner.

    Do this instead
    if (p != nullptr) { std::cout << *p; }

Applying the Rule

EASY

Rewrite the following snippet so that it follows the recommendation: int* ptr = 0; if (ptr == 0) { return; } Then explain in one sentence why your version is easier for a reader to understand.

Hints
  • Replace each 0 that represents the null pointer value with nullptr.
  • Check whether the reader can tell at a glance that the pointer is being compared to the null pointer value.

What to Remember

  1. 1
    The source recommends using nullptr rather than 0 or NULL for the null pointer value.
  2. 2
    nullptr states the intent directly, so a reader does not have to decide whether a 0 is a number or a pointer.
  3. 3
    Initialize pointers with nullptr and compare them against nullptr before using them.
  4. 4
    Avoid mixing 0, NULL, and nullptr in the same codebase.

At a glance

  • The source recommends using nullptr rather than 0 or NULL for the null pointer value.
  • nullptr makes the intent explicit, so readers do not have to interpret a 0 or NULL as a pointer value.
  • Initialize pointers with nullptr and compare them against nullptr before use.
  • Avoid mixing 0, NULL, and nullptr in the same codebase so the meaning stays clear.

Related concepts

More concepts starting with P