본문으로 건너뛰기 C++ nullptr vs NULL | Type-Safe Null Pointers

C++ nullptr vs NULL | Type-Safe Null Pointers

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

nullptrNULL0
Typestd::nullptr_tintegralint
Overloadspointerintint
Template Tnullptr_tintint
RecommendedYesLegacyLegacy

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

  1. nullptr: C++11 pointer literal
  2. NULL: legacy macro, integral
  3. Overloads: nullptr selects pointer overloads
  4. Templates: clear deduction
  5. Performance: no runtime difference
    Principles: Prefer nullptr in C++11+; compare with == nullptr or !ptr. Related: C++ nullptr, Smart pointers.

Keywords

C++, nullptr, NULL, null pointer, C++11, std::nullptr_t.


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.


Other articles related to this topic.


Keywords Covered in This Article (Related Search Terms)

This article covers C++, nullptr, NULL, pointers, C++11.