{"id":5412,"date":"2018-03-26T18:55:38","date_gmt":"2018-03-26T18:55:38","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/no-new-new\/"},"modified":"2023-06-26T11:53:46","modified_gmt":"2023-06-26T11:53:46","slug":"no-new-new","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/no-new-new\/","title":{"rendered":"No New New: Raw Pointers Removed from C++"},"content":{"rendered":"<p>Two weeks ago, the ISO C++ standard meeting took place in Jacksonville.&nbsp; Today I want to make a short detour and write about the revolutionary decision that was made in the Jacksonville meeting. Additionally, I refer to the post C++<a href=\"https:\/\/www.fluentcpp.com\/2018\/04\/01\/cpp-will-no-longer-have-pointers\/\">&nbsp;Will no Longer Have Pointers<\/a> by Fluent C++. The standard committee decided that pointers will be deprecated in C++20 and will, with a very high probability, be removed in C++23.<\/p>\n<p><!--more--><\/p>\n<p>Honestly, what seems like a revolution is only the last step in a long evolution. First, let me explain the big picture.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5411\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/memory.png\" alt=\"memory\" width=\"600\" height=\"237\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/memory.png 924w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/memory-300x119.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2018\/03\/memory-768x303.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h3>The evolution of pointers in C++<\/h3>\n<p>Pointers have been part of C++ since the first beginning. We got them from C. From the first beginning, there was always the tendency in C++ to make the handling with pointers more type-safe without paying the extra cost.<\/p>\n<p>With C++98 we got <span style=\"font-family: courier\\ new, courier;\">std::auto_ptr <\/span>to express&nbsp;exclusive ownership. But <span style=\"font-family: courier\\ new, courier;\">std::auto_ptr <\/span>had a&nbsp;big issue.<span style=\"font-family: courier\\ new, courier;\">&nbsp;When<\/span>&nbsp;you copy a <span style=\"font-family: courier\\ new, courier;\">std::auto_ptr&nbsp;<\/span><span style=\"font-family: courier\\ new, courier;\"><span>t<\/span><\/span>he resource will be moved. What looks like a copy operation was a move operation. The graphic shows the surprising behavior of a <span style=\"font-family: courier\\ new, courier;\">std::auto_ptr<\/span>.<span style=\"font-family: courier\\ new, courier;\"><span><br \/><\/span><\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5061\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/autoPtrCopy.jpg\" alt=\"autoPtrCopy\" width=\"400\" height=\"174\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/autoPtrCopy.jpg 643w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/autoPtrCopy-300x131.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>This was extremely bad and the reason for many serious bugs; therefore, we got <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span> with C++11, and <span style=\"font-family: courier\\ new, courier;\">std::auto_ptr<\/span> was deprecated in C++11 and finally removed in C++17. Additionally, we got <span style=\"font-family: courier\\ new, courier;\">std::shared_ptr<\/span> and <span style=\"font-family: courier\\ new, courier;\">std::weak_ptr<\/span> in C++11 for handling shared ownership. You can not copy but move a <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span>, and if you copy or assign a <span style=\"font-family: courier\\ new, courier;\">std::shared_ptr<\/span>, the internal reference counter will be increased. Have a look here:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5062\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/uniquePtrCopy.jpg\" alt=\"uniquePtrCopy\" width=\"400\" height=\"159\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/uniquePtrCopy.jpg 643w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/uniquePtrCopy-300x119.jpg 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5064\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.jpg\" alt=\"sharedPtr\" width=\"500\" height=\"284\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr.jpg 829w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr-300x170.jpg 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/sharedPtr-768x436.jpg 768w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>Since C++11 C++ has a multithreading library, this makes the handling with <span style=\"font-family: 'courier new', courier;\">std::shared_ptr<\/span> quite challenging because a <span style=\"font-family: 'courier new', courier;\">std::shared_ptr<\/span> is per definition shared but not thread-safe. Only the control block is thread-safe but not the access to its resource. That means modifying the reference counter is an atomic operation and you have the guarantee that the resource will be deleted exactly once. This is the reason we will get C++20 atomic smart pointers: <span style=\"font-family: courier\\ new, courier;\">std::atomic_shared_ptr<\/span> and <span style=\"font-family: courier\\ new, courier;\">std::atmic_weak_ptr<\/span>. Read the details in the proposal: <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/papers\/2014\/n4058.pdf\">Atomic Smart Pointers<\/a>.<\/p>\n<p>Now to the more exciting part of C++20 and C++23. Pointers will be deprecated in C++20 and removed in C++23. Or to say it with three words: <strong>N<\/strong>o <strong>N<\/strong>ew <strong>N<\/strong>ew (NNN).<\/p>\n<h3>std::unique_ptr to our rescue<\/h3>\n<p>But hold, we have a dogma in C++: Don&#8217;t pay for anything you don&#8217;t need. How can we program without a pointer? Just use an <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr.<\/span> A <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span> is by design as fast and as slim as a raw pointer but has a great benefit: it automatically manages its resource.<\/p>\n<p>Only to remind you. Here is a simple performance test.<\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ all.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">static<\/span> <span style=\"color: #006699; font-weight: bold;\">const<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> numInt<span style=\"color: #555555;\">=<\/span> <span style=\"color: #ff6600;\">100000000<\/span>;\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> start <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>system_clock<span style=\"color: #555555;\">::<\/span>now();\r\n\r\n  <span style=\"color: #006699; font-weight: bold;\">for<\/span> ( <span style=\"color: #007788; font-weight: bold;\">long<\/span> <span style=\"color: #007788; font-weight: bold;\">long<\/span> i<span style=\"color: #555555;\">=<\/span><span style=\"color: #ff6600;\">0<\/span> ; i <span style=\"color: #555555;\">&lt;<\/span> numInt; <span style=\"color: #555555;\">++<\/span>i){\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> tmp(<span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>(i));\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> tmp;\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::shared_ptr&lt;int&gt; tmp(new int(i));<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::shared_ptr&lt;int&gt; tmp(std::make_shared&lt;int&gt;(i));<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::unique_ptr&lt;int&gt; tmp(new int(i));<\/span>\r\n    <span style=\"color: #0099ff; font-style: italic;\">\/\/ std::unique_ptr&lt;int&gt; tmp(std::make_unique&lt;int&gt;(i));<\/span>\r\n  }\r\n\r\n  std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>duration<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">double<\/span><span style=\"color: #555555;\">&gt;<\/span> dur<span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>chrono<span style=\"color: #555555;\">::<\/span>system_clock<span style=\"color: #555555;\">::<\/span>now() <span style=\"color: #555555;\">-<\/span> start;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"time native: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> dur.count() <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\" seconds\"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The program allocates and deletes 100.000.000 ints.&nbsp; I use a raw pointer, <span style=\"font-family: courier\\ new, courier;\">std::shared_ptr,<\/span> and <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span> in two variations. I executed the program with and without maximum optimization on Linux and Windows. Here are the numbers.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5057\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/comparisonEng.png\" alt=\"comparisonEng\" width=\"600\" height=\"142\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/comparisonEng.png 901w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/comparisonEng-300x71.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/comparisonEng-768x182.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>The numbers show it black on blue. The two variations of <span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span> are as fast as the raw pointers on Linux and Windows. For the details of the numbers, read my previous post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/memory-and-performance-overhead-of-smart-pointer\">Memory and Performance Overhead of Smart Pointers<\/a>.<\/p>\n<h3>Ownership semantic<\/h3>\n<p>We use pointers, particularly raw pointers, far too often. The question if you should use a pointer boils down to one question: Who is the owner? Luckily, we can directly express our intention about ownership in code.<\/p>\n<ul>\n<li><strong>Local objects<\/strong>. The C++ runtime, as the owner, automatically manages the lifetime of these resources. The same holds for global objects or members of a class. The guidelines call them scoped objects.<\/li>\n<li><strong>References<\/strong>: I&#8217;m not the owner. I only borrowed resources that could not be empty.<\/li>\n<li><strong>Raw pointers<\/strong>: I&#8217;m not the owner. I only borrowed the resource that can be can be empty. I must not delete the resource.<\/li>\n<li><strong><span style=\"font-family: courier\\ new, courier;\">std::unique_ptr<\/span><\/strong>: I&#8217;m the exclusive owner of the resource. I may explicitly release the resource.<\/li>\n<li><strong><span style=\"font-family: courier\\ new, courier;\">std::shared_ptr<\/span><\/strong>: I share the resource with other shared ptr. I may explicitly release my shared ownership.<\/li>\n<li><strong><span style=\"font-family: courier\\ new, courier;\">std::weak_ptr<\/span><\/strong>: I&#8217;m not the owner of the resource, but I may become temporary the shared owner of the resource by using the method <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/memory\/weak_ptr\/lock\"><span style=\"font-family: courier\\ new, courier;\">std::weak_ptr::lock<\/span><\/a>.<\/li>\n<\/ul>\n<p>We have only to change our practice in one out of six use cases, and we are okay with the next evolution step in C++.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>Sorry for the detour, but the Jacksonville decision was worth a detour. The next post will be about the rules for performance in the C++ Core Guidelines.<\/p>\n<h2>Further Information<\/h2>\n<p>The decision to the next pdf bundle is made. It will take me about a week to prepare the pdf-bundles. First, I have to look for typos. People already subscribed to my newsletter will get them automatically.<\/p>\n<ul>\n<li>English: <a href=\"https:\/\/www.modernescpp.com\/index.php\/which-pdf-bundle-should-i-provide-make-your-choice-2\">Functional Features in C++<\/a><\/li>\n<li>German: <a href=\"https:\/\/www.grimm-jaud.de\/index.php\/blog\/welches-pdf-paeckchen-soll-ich-zusammenstellen-mache-dein-kreuz-3\">Charakteristiken der funktionalen Programmierung<\/a><\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Two weeks ago, the ISO C++ standard meeting took place in Jacksonville.&nbsp; Today I want to make a short detour and write about the revolutionary decision that was made in the Jacksonville meeting. Additionally, I refer to the post C++&nbsp;Will no Longer Have Pointers by Fluent C++. The standard committee decided that pointers will be [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":5411,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[360],"tags":[482],"class_list":["post-5412","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","tag-outdated"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5412","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5412"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5412\/revisions"}],"predecessor-version":[{"id":6833,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5412\/revisions\/6833"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5411"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5412"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5412"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5412"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}