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
#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
#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
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
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
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
struct Node {
int data;
Node* next;
Node(int d) : data(d), next(nullptr) {}
};
Repository returning “not found”
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.
Related posts
Keywords
C++, nullptr, NULL, null pointer, C++11, std::nullptr_t.
More links
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Why C++11 nullptr beats NULL and literal 0: std::nullptr_t, overload resolution, template deduction, and migration tips …
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence. See the C++ series index for the full picture.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
Keywords Covered in This Article (Related Search Terms)
This article covers C++, nullptr, NULL, pointers, C++11.