[2026] C++ nullptr vs NULL | Type-Safe Null Pointers
이 글의 핵심
Why C++11 nullptr beats NULL and literal 0: std::nullptr_t, overload resolution, template deduction, and migration tips including clang-tidy modernize-use-nullptr.
Introduction
nullptr (C++11) is a type-safe null pointer literal. Unlike NULL or 0, it has type std::nullptr_t and participates correctly in overload resolution and template deduction.
1. Basics
아래 코드는 cpp를 사용한 구현 예제입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <iostream>
int main() {
int* ptr1 = NULL; // implementation-defined (often 0)
int* ptr2 = 0; // integer literal
int* ptr3 = nullptr; // std::nullptr_t -> pointer
std::cout << ptr1 << "\n";
std::cout << ptr2 << "\n";
std::cout << ptr3 << "\n";
return 0;
}
std::nullptr_t overloads
다음은 cpp를 활용한 상세한 구현 코드입니다. 필요한 모듈을 import하고. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
#include <cstddef>
void func(std::nullptr_t) {
std::cout << "nullptr_t\n";
}
void func(int) {
std::cout << "int\n";
}
int main() {
func(nullptr); // nullptr_t
// func(NULL); // ambiguous or wrong: usually calls int
func(0); // int
return 0;
}
2. Problems with NULL
Overload resolution
아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
void process(int value) {
std::cout << "int: " << value << "\n";
}
void process(int* ptr) {
std::cout << "pointer\n";
}
int main() {
process(0); // int
process(NULL); // often int—not pointer!
process(nullptr); // pointer overload
return 0;
}
NULL is typically 0 or 0L—an integer, not a pointer type.
Template deduction
아래 코드는 cpp를 사용한 구현 예제입니다. 각 부분의 역할을 이해하면서 코드를 살펴보시기 바랍니다.
template<typename T>
void func(T value) {
std::cout << typeid(T).name() << "\n";
}
int main() {
func(0); // T = int
func(NULL); // T = int or long
func(nullptr); // T = std::nullptr_t
return 0;
}
auto deduction
auto p1 = NULL; // integral
auto p2 = nullptr; // std::nullptr_t
int* q = p2; // OK
3. Using nullptr
Initialization
다음은 간단한 cpp 코드 예제입니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
int* p1 = nullptr;
std::unique_ptr<int> u = nullptr;
std::shared_ptr<int> s = nullptr;
void (*fp)() = nullptr;
Checks
if (ptr == nullptr) { }
if (!ptr) { }
if (ptr) { }
Return values
int* find(int) {
return nullptr; // clear “no result”
}
4. Examples
Linked list
아래 코드는 cpp를 사용한 구현 예제입니다. 클래스를 정의하여 데이터와 기능을 캡슐화하며. 코드를 직접 실행해보면서 동작을 확인해보세요.
struct Node {
int data;
Node* next;
Node(int d) : data(d), next(nullptr) {}
};
Repository returning “not found”
다음은 간단한 cpp 코드 예제입니다. 조건문으로 분기 처리를 수행합니다. 코드를 직접 실행해보면서 동작을 확인해보세요.
User* findById(int id) {
if (id == 1) return &someUser;
return nullptr;
}
5. Comparison table
nullptr | NULL | 0 | |
|---|---|---|---|
| Type | std::nullptr_t | integral | int |
| Overloads | pointer | int | int |
Template T | nullptr_t | int | int |
| Recommended | Yes | Legacy | Legacy |
6. Migration
Before
int* ptr = NULL;
if (ptr == NULL) { }
void f(Widget* w = NULL);
After
int* ptr = nullptr;
if (ptr == nullptr) { }
void f(Widget* w = nullptr);
clang-tidy
clang-tidy -checks='-*,modernize-use-nullptr' -fix program.cpp
Summary
- nullptr: C++11 pointer literal
- NULL: legacy macro, integral
- Overloads:
nullptrselects pointer overloads - Templates: clear deduction
- Performance: no runtime difference
Principles: Prefernullptrin C++11+; compare with== nullptror!ptr. Related: C++ nullptr, Smart pointers.