Without new: Pointers will be removed from C ++
- Transfer
Two weeks ago, a committee of the ISO C ++ standard met in Jacksonville. Today I want to introduce a short summary and write about the revolutionary decision made at the Jacksonville meeting. For more information, I recommend reading a C ++ article that will no longer have pointers . The language standardization committee has decided that pointers will be deprecated in C ++ 20 and will most likely be deleted from C ++ 23.
Frankly, what seems revolutionary is just the last step in a long evolution.
Pointer evolution in C ++
Pointers exist in C ++ from the very beginning. We got them from C. From the very beginning of the development of C ++, there has always been a tendency to make pointer management more secure without significant loss.
In C ++ 98, we got std::auto_ptr
to express exceptional ownership. But he std::auto_ptr
had a big flaw. When you copy std::auto_ptr
, ownership of the resource is transferred to the copy. Copying looked like moving. The image below shows unpleasant behavior std::auto_ptr
.
It was very bad, leading to many serious bugs. Therefore, we got it std::unique_ptr
in C ++ 11, and declared it std::auto_ptr
deprecated in C ++ 11, and finally removed it from C ++ 17. Additionally, we got std::shared_ptr
it std::weak_ptr
in C ++ 11 for managing ownership. You cannot copy, but you can move std::unique_ptr
, and if you copy or assign std::shared_ptr
, the reference pointer counter increases. Look here:
Starting with C ++ 11, C ++ has a multi-threaded library. This makes management std::shared_ptr
quite complicated, because std::shared_ptr
by definition it is shared, but not thread safe. Only the control part with counters is thread-safe, but not access to the address of the monitored resource. This means that changing the counter is an atomic operation, but you have no guarantee that the resource will be deleted exactly once. For this reason, we get atomic smart pointers in C ++ 20: std::atomic_shared_ptr
and std::atmic_weak_ptr
. For details of the proposals of the standardization committee, read here: Atomic smart pointers .
Now let's move on to the more interesting parts of future C ++ 20 and C ++ 23 standards. Pointers will be deprecated in C ++ 20 and removed from C ++ 23. Let's say three words: No New New (NNN).
std :: unique_ptr will save us
But wait, how is the C ++ dogma: Don’t pay for what you don’t need. How can we program without pointers? Just use it std::unique_ptr
. From its design, it std::unique_ptr
is as fast and economical as a regular pointer, and has a clear advantage - automatic resource management.
Below is a simple performance test.
// all.cpp
#include
#include
static const long long numInt= 100000000;
int main(){
auto start = std::chrono::system_clock::now();
for ( long long i=0 ; i < numInt; ++i){
int* tmp(new int(i));
delete tmp;
// std::shared_ptr tmp(new int(i));
// std::shared_ptr tmp(std::make_shared(i));
// std::unique_ptr tmp(new int(i));
// std::unique_ptr tmp(std::make_unique(i));
}
std::chrono::duration dur= std::chrono::system_clock::now() - start;
std::cout << "time native: " << dur.count() << " seconds" << std::endl;
}
This program allocates and frees memory for 100 million int
. I use pointers, std::shared_ptr
and std::unique_ptr
in two variations. I am compiling a program with and without maximum optimization on Linux and on Windows. The following numbers are obtained:
Two variations std::unique_ptr
on Linux and Windows show the same performance as regular pointers. For the details of this test, see my last article: Memory Consumption and Smart Pointer Performance .
Semantics of ownership
Honestly, we use pointers and, in particular, regular pointers very often. The question of whether you should use a pointer comes down to the following: Who is the owner? Fortunately, with the help of code, we can clearly express this.
- Local objects . Rantime C ++ as the owner automatically controls the life of such resources. The same applies to global objects or class members. Directories reduce this to scope.
- Links : I am not the owner. I only ensure that the resource cannot be empty.
- Regular pointers : I am not the owner. I only refer to the resource, if any. I should not delete the resource.
- std :: unique_ptr : I am the exclusive owner of the resource. I can explicitly free my resource.
- std :: shared_ptr : I share the resource with others
std::shared_ptr
. I can explicitly delete my shared resource if no one else needs it. - std :: weak_ptr : I am not the owner of the resource, but I can temporarily split the resource when calling my method
std::weak_ptr::lock
.
We will need to change only one of the six practices for using pointers, and we are happy about the next step in the development of C ++.