What Exactly Is Nullptr

What exactly is nullptr?

How is it a keyword and an instance of a type?

This isn't surprising. Both true and false are keywords and as literals they have a type ( bool ). nullptr is a pointer literal of type std::nullptr_t, and it's a prvalue (you cannot take the address of it using &).

  • 4.10 about pointer conversion says that a prvalue of type std::nullptr_t is a null pointer constant, and that an integral null pointer constant can be converted to std::nullptr_t. The opposite direction is not allowed. This allows overloading a function for both pointers and integers, and passing nullptr to select the pointer version. Passing NULL or 0 would confusingly select the int version.

  • A cast of nullptr_t to an integral type needs a reinterpret_cast, and has the same semantics as a cast of (void*)0 to an integral type (mapping implementation defined). A reinterpret_cast cannot convert nullptr_t to any pointer type. Rely on the implicit conversion if possible or use static_cast.

  • The Standard requires that sizeof(nullptr_t) be sizeof(void*).

How is nullptr defined?

In brief, nullptr is a value that can be assigned to a pointer to any type, and it is false in boolean context (unlike most pointers that are results of new/malloc, or referencing a valid object), and despite itself being a valid pointer, dereferencing it results in UB, as does in/decrementing it, and it is a sole value of a singleton type nullptr_t.

Something like this.

What happens we create a nullptr and use it in a IF condition in C++

  1. What happens when we create a nullptr?

You can create a null pointer, but not a nullptr. The keyword nullptr denotes a literal value, not something that can be created.

Based on your code, you meant to ask what happens when a pointer variable is assigned nullptr. The answer to that is that your variable becomes a null pointer, a pointer that points to nothing and that evaluates to false when used in a boolean context.

I mean does a new pointer object is created that holds the value 0(as address) or something else?

We usually think of the value of a null pointer as being zero, but technically an implementation could use a bit pattern that has some non-zero bits. As long as you do not look too closely at the compiled code, go ahead and think of null pointers as holding the address 0.

And if the address it holds is 0 then is that pointer pointing to a possibly valid address in the memory?

The value of a null pointer must be distinct from all potentially valid memory addresses. If 0 is possibly a valid memory address in an implementation, then that implementation must use a different bit pattern to represent null pointers. (I am not aware of any implementations that fall into this category.)


  1. What is happening when we use it in the IF statement ?

The condition of an if statement is contextually converted to bool. When converting to bool from a pointer, the null pointer value converts to false and all other values convert to true.

I mean is the IF statement checking whether the value that the pointer object holds is 0 or something else?

Something else (but only by a fine shade of meaning). It checks whether the value is the null pointer value (which is almost certainly represented by zero bits on your computer, but technically not guaranteed to be so).

What does * when using nullptr mean?

what does the * mean in

int* p = nullptr;

* refers to a pointer-to-an object which holds a specific location/address in memory, in your case it is a pointer-to-an-int and so it refers to the address of an integer.

Also, it would be helpful if anyone can example what nullptr means. Is it equivalent to null? Sorry, I recently started learning c++;

Both NULL and nullptr point to the zeroth address (0x000000) in memory.

In most cases, the C++11 keyword nullptr is similar to NULL in the sense that they usually point to the same thing. But, there are some subtle differences between the two:

decltype(NULL);    /* 'void*' or `intptr_t`, depends on implementation, the former is
* an object pointer type while the latter is just an integer that
* can hold an address */
decltype(nullptr); // Always 'std::nullptr_t'

From this, we find that nullptr is in fact, not a pointer but an instance of a class, std::nullptr_t.

Essentially, std::nullptr_t is a wrapper class which indirectly refers to the zeroth address in memory. All instances of this class (including nullptr) are implicitly convertible to the pointer of any type.

The reason for this sort of design was to facilitate function overloading, so that nullptr could have a consistent type that could be safely overloaded, unlike NULL which does not have a consistent type across different implementations:

#include <iostream>
#include <cstddef>

void f(long int) {
std::cout << "Encountered a long" << std::endl;
}

void f(decltype(NULL)) {
std::cout << "Encountered NULL" << std::endl;
}

void f(decltype(nullptr)) {
std::cout << "Encountered nullptr" << std::endl;
}

int main() {
f(0l);
f(NULL);
f(nullptr);
}

In this case, normally, one would think that this would output:

Encountered a long
Encountered NULL
Encountered nullptr

But it gets more complicated than this, on certain implementations, the compiler would give this error:

// Output from the GCC compiler:
source>:8:6: error: redefinition of 'void f(long int)'
8 | void f(decltype(NULL)) {
| ^

This is because decltype(NULL) is long int in this case (not always), which causes the overload void f(long int) to be defined twice, leading to a compilation error.

This is one of the use cases of nullptr. It safely retains its type, which is std::nullptr_t.

In contrast, NULL doesn't have any defined universal type, so it can't be safely overloaded in a function based on its type.

Can the NULL macro actually be a nullptr?

While nullptr is a null pointer constant, it is not a null pointer value. The latter is a value of some pointer type, which std::nullptr_t is not.

Reference:

A null pointer constant is an integer literal (5.13.2) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is
distinguishable from every other value of object pointer or function pointer type. Such a conversion is called
a null pointer conversion. [...]

7.11/1 in N4659, emphasize mine

So NULL can indeed be nullptr without providing the arithmetic operators.

C++ Style: When using c function in c++, should I check for NULL or nullptr?

From the cppreference on nullptr, you can see that there is implicit conversion from nullptr to NULL. So you can do either but (as good practice) better use nullptr from C++11 onwards.

The keyword nullptr denotes the pointer literal. It is a prvalue of type std::nullptr_t. There exist implicit conversions from nullptr to null pointer value of any pointer type and any pointer to member type. Similar conversions exist for any null pointer constant, which includes values of type std::nullptr_t as well as the macro NULL.

Is nullptr not a special keyword and an object of std::nullptr_t? [duplicate]

It is a keyword, the standard draft says (lex.nullptr):

The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t.

the nullptr is not yet a pointer, but it can be converted to a pointer type. This forbids your above assignment, which is an assignment to an unrelated reference type, in which case no conversion is possible (consider int& a = 1.f;!).

Doing #define NULL nullptr shouldn't alter the behaviour unless you did use NULL in a context such as int i = 4; if(NULL == i) {}, which won't work with nullptr because nullptr is can't be treated as an integer literal.

I don't think there are many other use-cases for std::nullptr_t, it's just a sentinel because nullptr needs a type.



Related Topics



Leave a reply



Submit