Explain nullptr and nullptr_t

Share the Article

What is the problem with NULL?

Traditionally, C & C++ programs are using NULL macro to denote null pointer. This macro is actually not a pointer but an integer constant value 0. However, there are fundamental problems in using this macro. The nullptr ultimately solves those problems in C++11.

Firstly, the underlying implementations may assign this to any of integral types. For instance, depending on the platform, the 0 value may either be an “int” or may be a “long”. Consequently, due to overloading on any of integral or pointer types may provide unexpected results.

The following example shows the a call to overloaded function “fun” shall give unexpected result. In particular, the first overload expects an integer type argument and second overload expects a pointer. However, when NULL value is passed, the compiler will get confused. This is because with NULL the user may want to call the pointer version. However, since, the implementation is done using integral type, therefore, integral version is also possible match.

#include <iostream> //main header using namespace std; //namespace void funda(int) { cout << "funda(int)" << endl; } void funda(int*) { cout << "funda(int*)" << endl; } int main() { funda(NULL); return 0; }

The error thrown by compiler is:

compiler error due to not using nullptr and having ambiguous overloads

Understanding nullptr

In C++11, nullptr will solve this ambiguity. Therefore, when we make following changes, the compiler will correctly compile the code.

// fun(NULL); fun(nullptr);

The output that will be generated with above command is:

fun(int*)

How nullptr is different than NULL

nullptr do not have either an integral type or even a pointer type. The actual type of nullptr is nullptr_t instead. This is just like a pointer which can point to all data types. Therefore, when program passes nullptr, the compiler identifies that this value can get converted only to a pointer. Finally, correct overload is called.

Address of an object of nullptr_t type

It is possible to define any variable of type nullptr_t. This definition will be just like a normal variable definition. Therefore, it is valid to take the address of such a variable using ampersand (&) operator.

nullptr_t np; //np is like nullptr nullptr_t * ptr_np = &np; cout << ptr_np << endl;

The above code may generate an output, like, shown below.

0x7ffc48955e50

Address of nullptr

It is not possible to take the address of nullptr. This is because internally, it is an R-value of type nullptr_t.

nullptr_t *ptr_np = &nullptr;

For the above code, the compiler may generate an error:

compiler error for trying to access address of nullptr

Assignment to any pointer

The constant nullptr can be assigned to any pointer or to pointer to member. For instance, it can be assigned to any of the following types.

int *p = nullptr; char *q = nullptr; float *r = nullptr; void *s = nullptr;

However, this value cannot be assigned to non-pointer.

int t = nullptr; //This is wrong

Compiler error:

compiler error due to converting nullptr to int

Using sizeof & typeinfo

Since, the nullptr is like another variable, we can use sizeof and typeid. The following code is valid and produces output shown below.

cout << sizeof(nullptr) << endl; cout << typeid(nullptr).name() << endl;

Output:

8 Dn

Comparison Operation

It is valid to compare two objects of type nullptr_t. This is because, they are just like ordinary variables of type nullptr_t. Also, we can compare an object and nullptr. nullptr is just like a constant of this type.

nullptr_t n1, n2; if(n1 == n2) cout << "Equal" << endl; else cout << "Not-Equal" << endl; if(n1 == nullptr) cout << "Equal to nullptr" << endl; else cout << "Not-Equal to nullptr" << endl;

Output

Equal Equal to nullptr

Declaration using decltype

The decltype keyword returns the actual data type of any object. And this is true for nullptr also. The following example shows that this decltype actually returns a type “nullptr_t”.

decltype(nullptr) z; if(z == nullptr) cout << "This is nullptr" << endl;

Output

This is nullptr

Main Funda: nullptr is a new keyword in C++11 and it denotes an object of type nullptr_t

Related Topics:

 What are the drawbacks of using enum ?
Which member functions are generated by compiler in class?
How to stop compiler from generating special member functions?
Compiler Generated Destructor is always non-virtual
How to make a class object un-copyable?
Why virtual functions should not be called in constructor & destructor ?
Explaining C++ casts
How pointer to class members are different ?
How std::forward( ) works?
Rule of Three
How std::move() function works?
What is reference collapsing?
How delete keyword can be used to filter polymorphism
emplace_back vs push_back


Share the Article

Leave a Reply

Your email address will not be published. Required fields are marked *