In C++, both NULL and nullptr are used to represent null pointers. However, they have significant differences in terms of type safety, functionality, and usage. Let’s break this down.
1. NULL
Definition
NULLis a macro that is traditionally used to represent a null pointer constant in C and C++.- It is defined in
<cstddef>or<cstdlib>as:#define NULL 0
Characteristics
- Integer value: Since
NULLis typically defined as0, it is essentially treated as an integer constant. - Lacks type safety: Because
NULLis just0, it doesn’t have a specific pointer type. This can lead to ambiguity when overloaded functions are called.
Examples
-
Assigning NULL to a pointer:
int* ptr = NULL; // Equivalent to int* ptr = 0;
-
Problem with function overloading:
voidfoo(int x); voidfoo(int* ptr); foo(NULL); // Ambiguity: Does it call foo(int) or foo(int*)?
This is because
NULLis treated as0, which can match bothintandint*.
2. nullptr (C++11 and later)
Definition
nullptris a keyword introduced in C++11 to provide a type-safe null pointer constant.- It has its own distinct type:
std::nullptr_t.
Characteristics
- Type-safe: Unlike
NULL,nullptrcannot be implicitly converted to types other than pointers. - Clear semantics: When using
nullptr, it is clear that it represents a null pointer and not an integer. - Solves ambiguity: It eliminates ambiguity in overloaded function calls.
Examples
-
Assigning nullptr to a pointer:
int* ptr = nullptr; // A null pointer of type int*
-
Distinguishing overloaded functions:
voidfoo(int x); voidfoo(int* ptr); foo(nullptr); // Calls foo(int*), because nullptr is explicitly a pointer.
-
nullptrin conditional checks:if (ptr == nullptr) { std::cout << "Pointer is null.\n"; }
3. std::nullptr_t
std::nullptr_tis the type ofnullptr.- It can implicitly convert to any pointer type or pointer-to-member type.
- Example:
std::nullptr_t nptr = nullptr; int* intPtr = nptr; // Valid void* voidPtr = nptr; // Valid
4. Comparison of NULL and nullptr
| Feature | NULL | nullptr |
|---|---|---|
| Type | Macro (typically 0) | std::nullptr_t |
| Introduced in | C (inherited by C++) | C++11 |
| Type Safety | No | Yes |
| Ambiguity in Overloading | Yes | No |
| Usage | Obsolete (not recommended) | Recommended |
5. Why Use nullptr Over NULL?
-
Type Safety:
nullptrensures that the value is treated as a pointer, avoiding potential bugs. -
Clarity: Code readability improves since
nullptrexplicitly conveys its purpose as a null pointer. -
Future-Proofing: Since
NULLis tied to legacy code, usingnullptraligns better with modern C++ practices.
6. Code Comparison
Using NULL (Legacy Approach):
#include<iostream>
intmain(){
int* ptr = NULL; // Assigning NULL to a pointer
if (ptr == NULL) {
std::cout << "Pointer is null (NULL).\n";
}
return0;
}
Using nullptr (Modern Approach):
#include<iostream>
intmain(){
int* ptr = nullptr; // Assigning nullptr to a pointer
if (ptr == nullptr) {
std::cout << "Pointer is null (nullptr).\n";
}
return0;
}
Conclusion
- Use
nullptr: If you are writing C++ code in modern environments (C++11 or later), always prefernullptroverNULL. NULLis a remnant of C and is not type-safe, whereasnullptris specifically designed for C++ and eliminates ambiguity, making it the recommended choice for null pointers in modern C++ development.