Avatar
Game programmer.
Write about game programming, Unreal Engine and C++

TNonNullPtr — Non-Nullable Raw Pointers in Unreal Engine

What is TNonNullPtr

TNonNullPtr<T> is a non-nullable, non-owning raw pointer that guarantees the pointer is never nullptr. It wraps a T* but bans null at compile-time and runtime via ensureMsgf.

TNonNullPtr<AActor> ActorPtr(SomeValidActor);  // OK
TNonNullPtr<AActor> Bad(nullptr);              // Banned + ensure failure

Problem

Raw pointers require constant null checks:

void DoSomething(ATestActor* TestActor)
{
    if (TestActor)
    {
        TestActor->DoMagic();
    }
}

This leads to:

  • Boilerplate null checks
  • Runtime crashes if someone accidentally passes nullptr
  • Cognitive overhead: “Wait, can this be null or not?”

Solution

TNonNullPtr<T> wraps a raw pointer but forbids null:

void DoSomething(ATestActor* TestActor)
{
    TestActor->DoMagic(); // No null check needed!
}

If anyone tries to pass nullptr literal, it fails at compile-time. Passing nullptr via a variable triggers ensureMsgf at runtime:

ATestActor* TestActorRaw = nullptr;
TNonNullPtr<ATestActor> Safe(TestActorRaw); // ensureMsgf: "Tried to initialize TNonNullPtr with a null pointer!"

Key features

Construction

ATestActor* ValidTestActor = GetTestActor();
TNonNullPtr<ATestActor> TestActor(ValidTestActor);  // OK

TNonNullPtr<ATestActor> TestActor(nullptr);         // Compile-time banned + ensure in debug

Construction

ATestActor* ValidTestActor = GetTestActor();
TNonNullPtr<ATestActor> TestActor(ValidTestActor);  // OK

TNonNullPtr<ATestActor> TestActor(nullptr);         // Compile-time banned + ensure in debug

Assignment

TestActor = AnotherValidTestActor;      // OK
TestActor = nullptr;                    // Banned

Functions

TArray<TNonNullPtr<ATestActor>> GetTestActors()
{
    TArray<TNonNullPtr<ATestActor>> TestActors;

    //...

    return TestActors;
}

Works with TOptional

TOptional<TNonNullPtr<ATestActor>> OptionalActor;
OptionalActor.Emplace(SomeValidActor);

if (OptionalActor)
{
    OptionalActor->DoMagic();
}

Implicit Conversion

ATestActor* RawTestActor = TestActor; // OK — but only after ensure

Best Practice

Use TNonNullPtr only when you control both sides and can guarantee validity.

// API contract: Caller MUST pass valid pointer
void TestFunction(TNonNullPtr<ATestActor> TestActor)
{
    // SAFE to use directly — IF caller respects contract
    TestActor->DoMagic();
}

When to use it?

Scenario Use TNonNullPtr<T>?
Function parameter guaranteed non-null Yes
Return value from a function that never returns null Yes
Class member that is always valid after construction Yes
Temporary pointer that might be null No → use TObjectPtr<T>, raw pointer, or TOptional<T>