TNonNullPtr — Non-Nullable Raw Pointers in Unreal Engine
Published on 22 Oct 2025
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> |