What are the advantages of using nullptr?
In that code, there doesn't seem to be an advantage. But consider the following overloaded functions:
void f(char const *ptr);
void f(int v);
f(NULL); //which function will be called?
Which function will be called? Of course, the intention here is to call f(char const *)
, but in reality f(int)
will be called! That is a big problem1, isn't it?
So, the solution to such problems is to use nullptr
:
f(nullptr); //first function is called
Of course, that is not the only advantage of nullptr
. Here is another:
template<typename T, T *ptr>
struct something{}; //primary template
template<>
struct something<nullptr_t, nullptr>{}; //partial specialization for nullptr
Since in template, the type of nullptr
is deduced as nullptr_t
, so you can write this:
template<typename T>
void f(T *ptr); //function to handle non-nullptr argument
void f(nullptr_t); //an overload to handle nullptr argument!!!
1. In C++, NULL
is defined as #define NULL 0
, so it is basically int
, that is why f(int)
is called.
What are the advantages/disadvantages of std::optional over nullptr?
The sole job of std::optional
is to extend the type domain by an additional "null" value. Every pointer type T*
already has a value considered "null" - nulltpr
.
Thus, it's not a good idea to compare those two directly, because they answer different questions. Sometimes it's important to differentiate between "no result" and "null result"1 (which is one of the possible interpretations), sometimes it's not. You should use whichever fits your needs.
Now if the only reason the code returned a pointer was to make use of the implicit pointer nullability, then the proper solution would be to change it to return std::optional<SomePointer>
(or perhaps std::optional<std::reference_wrapper<SomePointer>>
) instead, but that's not what you asked about.
1 Of course at this point it's also worthwhile to consider something like e.g. struct NoResult {}; using Result = std::variant<NoResult, SomePointer*>;
to make it even more explicit.
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*)
.
Benefits of Null Safety
I will assume that you come from Java, you already looked at some explanations somewhere else and did not fully understand them. Therefore, I will not try to give you a comprehensive explanation (which you can find elsewhere) but instead I will try to make clear the core idea of null pointer safety.
There are two points that, if you understand them, should make it clear enough. First, there is the idea of having two separate types to represent what you would model as a single type in Java: nullable ones and not nullable ones. To give you an example, while in Java you put a string in a String
object, without caring if the string can be null or not, in Kotlin you have two types: String?
and String
. The first accepts null values (like the Java equivalent) but the second does not. So you can have null values in types with a ?
(like String?
or Int?
) but there are a lot of restrictions on what you can do with those: basically you are restricted to the things you can do with a null, because, after all, the variable could be holding a null value. So no calling of method on it, for instance. So, while in Java you could call a method on it and have a NullPointerException
sometimes, in Kotlin you cannot call any methods. And this is not because of some silent behavior of Kotlin, it’s much simpler than that: the compiler won’t let you. Try and you will see that the program does not compile. If the variable was of type String
instead of String?
then Kotlin would allow you to call methods from it.
So, basically, no null pointer exceptions because you can never call a method on an object variable that could be null.
But then, sometimes the variable is not null: so how could you call the method on the variable in those cases where the variable is not null? Again, the answer is simple: you have to check it. I mean, you have to use an if
instruction (explicitly or implicitly) that will check if the variable is null or not. Something like “if (myVariable != null) {call method on variable}
”. So, as you can see, the Kotlin compiler is clever enough to see that you used an if
instruction that guarantees that the variable is not null, so it will let you call methods on the variable in the block between {
and }
. In other words, if your variable is of type String?
but you are inside an if
block where you checked that the variable is not null, Kotlin will treat it like a variable of type String
instead of String?
When you speak about
some part the code which silently won't be executed
I am guessing you are thinking about some operators that have an implicit if
inside of them, like the ?.
operator. If you write
myVariable?.call()
it means roughly
if (myVariable != null) { myVariable.call()}
So, indeed, if the variable is null, it will “fail” silently. But this is not different than Java if you use the same kind of if
. In other words, nothing will happen if the variable is null because you explicitly coded it to behave like that.
using nullptr instead of NULL when mixing C and C++
Yes. nullptr is comparable to and equivalent to a null pointer of any other pointer type.
What is the difference between nullptr and nullptr_t in C++?
nullptr
is the constant, nullptr_t
is its type. Use each one in contexts where you need respectively a null pointer, or the type of a null pointer.
Using nullptr in API function calls?
Yes, you can safely use nullptr
anywhere you use NULL
.
NULL
expanded to an integer constant expression with the value zero, which could then be converted to a null pointer value of any type. nullptr
is "pointer literal" that does the exact same thing: it converts to a null pointer value of any type.
More information here.
Why is nullptr a part of the core language, but nullptr_t is a part of STL?
The proposal that introduced nullptr
, N2431, indicates in section 1.1 that it was desirable to not force users to include a header in order to use nullptr
.
It also remarks, "We do not expect to see much direct use of nullptr_t
in real programs". Thus, it was considered preferable to add nullptr_t
to the library rather than create a new keyword only to be used for this obscure purpose. In addition, if you don't want to include the header, you can always just write decltype(nullptr)
yourself.
Related Topics
Why Can Lambdas Be Better Optimized by the Compiler Than Plain Functions
How to Set Up Google C++ Testing Framework (Gtest) With Visual Studio 2005
Why Is 'This' a Pointer and Not a Reference
C/C++ Check If One Bit Is Set In, I.E. Int Variable
What Are the Pointer-To-Member Operators -≫* and .* in C++
Why Can't I Have a Non-Integral Static Const Member in a Class
What Is More Efficient? Using Pow to Square or Just Multiply It With Itself
Initializing Fields in Constructor - Initializer List VS Constructor Body
How to Construct a Std::String With an Embedded Null
How to Get the Ip Address of a Local Computer
Is the Size of Std::Array Defined by Standard
Efficient Implementation of Log2(_M256D) in Avx2
Converting a Pointer into an Integer
Efficient Way of Reading a File into an Std::Vector≪Char≫