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 typestd::nullptr_t
is a null pointer constant, and that an integral null pointer constant can be converted tostd::nullptr_t
. The opposite direction is not allowed. This allows overloading a function for both pointers and integers, and passingnullptr
to select the pointer version. PassingNULL
or0
would confusingly select theint
version.A cast of
nullptr_t
to an integral type needs areinterpret_cast
, and has the same semantics as a cast of(void*)0
to an integral type (mapping implementation defined). Areinterpret_cast
cannot convertnullptr_t
to any pointer type. Rely on the implicit conversion if possible or usestatic_cast
.The Standard requires that
sizeof(nullptr_t)
besizeof(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++
- 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.)
- 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 typestd::nullptr_t
. There exist implicit conversions fromnullptr
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 typestd::nullptr_t
as well as the macroNULL
.
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
C++11 Std::To_String(Double) - No Trailing Zeros
The Definitive C++ Book Guide and List
Why Can Templates Only Be Implemented in the Header File
What Are the Basic Rules and Idioms For Operator Overloading
Undefined Behavior and Sequence Points
What Is the Strict Aliasing Rule
Why Does Std::Getline() Skip Input After a Formatted Extraction
What Are Copy Elision and Return Value Optimization
Why Isn't Sizeof For a Struct Equal to the Sum of Sizeof of Each Member
Iterator Invalidation Rules For C++ Containers
Accessing an Array Out of Bounds Gives No Error, Why
How to Access a Local Variable from a Different Function Using Pointers
Default Constructor With Empty Brackets
When How to Use a Forward Declaration