{
    "componentChunkName": "component---src-templates-post-page-js",
    "path": "/2019/zero-cost-unique_ptr",
    "result": {"data":{"site":{"siteMetadata":{"title":"Solid Abstractions","siteUrl":"https://solidabstractions.com","twitterId":291334023,"author":{"fullName":"Julien Hartmann","profileHtml":"I am an open-source de­vel­op­er, for­mer IT con­sul­tant with a pas­sion for new tech­nol­o­gies. I be­lieve the role of an en­gi­neer is to em­pow­er peo­ple, by as­sem­bling sim­ple, re­fined de­signs.\n","links":[{"url":"https://github.com/spectras/","name":"github","title":"GitHub"},{"url":"https://stackoverflow.com/users/3212865/spectras","name":"stackoverflow","title":"StackOverflow"},{"url":"https://www.linkedin.com/in/julienhartmann/","name":"linkedin","title":"LinkedIn"}],"profilePicNode":{"original":{"src":"/static/profile-pic-301a9cbe7b572c3e7910c9717d2b3bcd.jpg"}},"url":"https://etherdream.org/about"}}},"markdownRemark":{"id":"8a92c50f-af2c-5633-8c7d-a8cc80e12b94","excerpt":"A C++ smart unique_ptr uses exactly the same amount of memory as a\nregular pointer, and has zero runtime cost. That is what we love about C++. But what if I need a custom deleter for my pointer? Can I get it at zero cost too?","html":"<p>A C++ smart unique_ptr uses exactly the same amount of memory as a\nregular pointer, and has zero runtime cost. <strong>That is what we love about C++</strong>.<br/></p>\n<p>But what if I need a custom deleter for my pointer? Can I get it at zero cost too?</p>\n<p>--- excerpt ---</p>\n<p>Smart pointers are a major feature of C++11 that changed the way the language works.\nThey come in two versions: <code class=\"language-text\">shared_ptr</code> for shared ownership and <code class=\"language-text\">unique_ptr</code> for exclusive ownership.</p>\n<p>In fact, <code class=\"language-text\">unique_ptr</code> represents an <em>owning</em> pointer. That's just like a good old\n<code class=\"language-text\">T *</code> pointer, except the compiler knows it owns its target, and will call <code class=\"language-text\">delete</code> for us\nas needed.</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-1\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">auto</span> <span class=\"token function\">function</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">const</span> std<span class=\"token double-colon punctuation\">::</span>string <span class=\"token operator\">&amp;</span> x<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">auto</span> ptr <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token generic-function\"><span class=\"token function\">make_unique</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>Foo<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>x<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token operator\">!</span><span class=\"token function\">someTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token keyword\">throw</span> <span class=\"token function\">Error</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"someTest failed\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> ptr<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div><figcaption><div class=\"figcaption-wrapper\">Throw, return, pass it around, it will not leak.</div></figcaption></figure></div>\n<p>And it does this with no overhead: a <code class=\"language-text\">unique_ptr</code> uses exactly the same amount of memory as a\nregular pointer, and has zero runtime cost. And <b>that is what we love about C++</b>.</p>\n<h2 id=\"why-a-custom-deleter\">Why a custom deleter?</h2>\n<p>I happen to have this amazing C library that I want to use:</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-2\"><div class=\"gatsby-highlight\" data-language=\"c\"><pre class=\"language-c\"><code class=\"language-c\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">external_api</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">int</span> data<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// other api-relevant state</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\nexternal_api <span class=\"token operator\">*</span> <span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    external_api <span class=\"token operator\">*</span> api <span class=\"token operator\">=</span> <span class=\"token function\">malloc</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>external_api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// initialize state here</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"External C api %p opened\\n\"</span><span class=\"token punctuation\">,</span> api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> api<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">void</span> <span class=\"token function\">close_my_api</span><span class=\"token punctuation\">(</span>external_api <span class=\"token operator\">*</span> api<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token function\">free</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">printf</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"External C api %p closed\\n\"</span><span class=\"token punctuation\">,</span> api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// Plenty other functions using data in external_api</span></code></pre></div><figcaption><div class=\"figcaption-wrapper\">A feature-packed C library. Actual implementation.</div></figcaption></figure></div>\n<p>Nothing complex so far. Assuming the header file is properly written, I can use it\nfrom C++ as usual:</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-3\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">void</span> <span class=\"token function\">do_something</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">auto</span> <span class=\"token operator\">*</span> api <span class=\"token operator\">=</span> <span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// do things using api</span>\n    <span class=\"token function\">close_my_api</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div><figcaption><div class=\"figcaption-wrapper\">Using the feature-packed library.</div></figcaption></figure></div>\n<p>Great! Just be sure to close the api, we don't want to leak it. It's fine, we are all great\ndevelopers who would never forget the closing part. And will never recruit any intern or\nforgetful colleague. Wait… what happens if any operation in the <em>do things</em> part throws\nan exception?</p>\n<div class=\"note\"><p>Now would be a good time to review Herb Sutter's\n<a href=\"http://www.gotw.ca/gotw/020.htm\" class=\"external\" rel=\"external noopener noreferrer\">Guru of the Week #20</a> on code complexity.\nIt shows how a very simple function has 3 regular code paths and 20 invisible\nexceptional paths, many of which even experienced developers don't identify correctly.</p></div>\n<p>Well… <strong>on exception we leak <code class=\"language-text\">api</code></strong>. Not good.</p>\n<p>In fact, we lost all the\n<a href=\"https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization\" class=\"external\" rel=\"external noopener noreferrer\">RAII</a>\nsafety goodness that <code class=\"language-text\">unique_ptr</code> usually provides us.\nBut wait, <code class=\"language-text\">api</code> is a pointer to some allocated memory right? Why don't we use <code class=\"language-text\">unique_ptr</code>?</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-4\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">void</span> <span class=\"token function\">do_something</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">auto</span> api <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token generic-function\"><span class=\"token function\">unique_ptr</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>external_api<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    cout <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">\"    -> pointer size is \"</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span>endl<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// do things using api</span>\n<span class=\"token punctuation\">}</span></code></pre></div><div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ./attempt1\nExternal C api 0x56365fe89e70 opened\n    -> pointer size is 8\nSegmentation fault</code></pre></div><figcaption><div class=\"figcaption-wrapper\">Initial attempt at using <code class=\"language-text\">unique_ptr</code> — not quite what we expected.</div></figcaption></figure></div>\n<p>The issue of course, is <code class=\"language-text\">unique_ptr</code> is not aware of <code class=\"language-text\">close_my_api()</code> and attempts to clear\n<code class=\"language-text\">api</code> using <code class=\"language-text\">delete</code>. It may or may not crash on your system, depending on whether <code class=\"language-text\">delete</code>\nrelies on <code class=\"language-text\">free</code> under the hood. In any case, it will <strong>never</strong> invoke <code class=\"language-text\">close_my_api()</code>.</p>\n<p>But the template library has a solution: <b>we can provide a custom deleter</b>.</p>\n<h2 id=\"failed-attempts\">Failed attempts</h2>\n<h3 id=\"working-naive-approach\">Working naive approach</h3>\n<p>Indeed, the full signature of <code class=\"language-text\">unique_ptr</code> reads like this:</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-5\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">template</span><span class=\"token operator\">&lt;</span><span class=\"token keyword\">class</span> <span class=\"token class-name\">T</span><span class=\"token punctuation\">,</span>\n         <span class=\"token keyword\">class</span> <span class=\"token class-name\">Deleter</span> <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span>default_delete<span class=\"token operator\">&lt;</span>T<span class=\"token operator\">>></span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">unique_ptr</span><span class=\"token punctuation\">;</span></code></pre></div><figcaption><div class=\"figcaption-wrapper\">Template signature of <code class=\"language-text\">unique_ptr</code>.</div></figcaption></figure></div>\n<p>So provided we fill in the correct template arguments, we can tell <code class=\"language-text\">unique_ptr</code> to use\n<code class=\"language-text\">close_my_api()</code> instead of <code class=\"language-text\">delete</code> to clean up:</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-6\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">void</span> <span class=\"token function\">do_something</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">using</span> Deleter <span class=\"token operator\">=</span> <span class=\"token keyword\">decltype</span><span class=\"token punctuation\">(</span><span class=\"token operator\">&amp;</span>close_my_api<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">auto</span> api <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token generic-function\"><span class=\"token function\">unique_ptr</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>external_api<span class=\"token punctuation\">,</span> Deleter<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span>\n        <span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> close_my_api\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    cout <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">\"    -> pointer size is \"</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span>endl<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// do things using api</span>\n<span class=\"token punctuation\">}</span></code></pre></div><div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ./attempt2\nExternal C api 0x55f0667dee70 opened\n    -> pointer size is 16\nExternal C api 0x55f0667dee70 closed</code></pre></div><figcaption><div class=\"figcaption-wrapper\">Using a custom deleter with <code class=\"language-text\">unique_ptr</code>.</div></figcaption></figure></div>\n<p>There is nothing <em>wrong</em> with this approach. It is correct and somewhat intuitive.\nIn fact, this approach is the one you\n<a href=\"https://stackoverflow.com/a/26360965/3212865\" class=\"external\" rel=\"external noopener noreferrer\">usually</a>\n<a href=\"https://stackoverflow.com/a/19054467/3212865\" class=\"external\" rel=\"external noopener noreferrer\">find</a> on\n<a href=\"https://stackoverflow.com/questions/45983701\" class=\"external\" rel=\"external noopener noreferrer\">StackOverflow</a>.</p>\n<p><b>But it is not zero-cost.<sup id=\"fnref-1\"><a href=\"#fn-1\" class=\"footnote-ref\">1</a></sup></b></p>\n<p>The size of the <code class=\"language-text\">api</code> pointer increased from 8 bytes to 16 bytes. That's a 100% increase.\nThe thing is we are now storing a copy of the address of <code class=\"language-text\">close_my_api()</code>\nin <strong>every <code class=\"language-text\">unique_ptr</code></strong>. Which is a complete waste, since we know for sure all <code class=\"language-text\">external_api</code>\nobjects will <em>always</em> be deleted with <code class=\"language-text\">close_my_api()</code>.</p>\n<p>This is C++. We want zero-cost. Surely there must be a better way?</p>\n<h3 id=\"hijacking-default_delete\">Hijacking default_delete</h3>\n<p>Coming back to the template signature of <code class=\"language-text\">unique_ptr</code>, we notice it uses and odd\n<code class=\"language-text\">default_delete</code> default deleter. How about customizing its behavior, like\n<a href=\"https://stackoverflow.com/a/16615285/3212865\" class=\"external\" rel=\"external noopener noreferrer\">this answer</a> suggests?</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-7\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token comment\">// INVALID - DO NOT DO THIS</span>\n<span class=\"token keyword\">template</span> <span class=\"token operator\">&lt;</span><span class=\"token operator\">></span> <span class=\"token keyword\">struct</span> <span class=\"token class-name\">std</span><span class=\"token operator\">:</span><span class=\"token base-clause\"><span class=\"token operator\">:</span><span class=\"token class-name\">default_delete</span><span class=\"token operator\">&lt;</span><span class=\"token class-name\">external_api</span><span class=\"token operator\">></span></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">void</span> <span class=\"token keyword\">operator</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>external_api <span class=\"token operator\">*</span> ptr<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">close_my_api</span><span class=\"token punctuation\">(</span>ptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">void</span> <span class=\"token function\">do_something</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">auto</span> api <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span><span class=\"token generic-function\"><span class=\"token function\">unique_ptr</span><span class=\"token generic class-name\"><span class=\"token operator\">&lt;</span>external_api<span class=\"token operator\">></span></span></span><span class=\"token punctuation\">(</span><span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    cout <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">\"    -> pointer size is \"</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span>endl<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// do things using api</span>\n<span class=\"token punctuation\">}</span></code></pre></div><figcaption><div class=\"figcaption-wrapper\">This is an <strong>illegal</strong> specialization of <code class=\"language-text\">std::default_delete</code>. Do not try this at home.</div></figcaption></figure></div>\n<p>It would seem to work, except <b>this is illegal</b>. Although specializing <code class=\"language-text\">default_delete</code>\nis indeed allowed, it must follow the rules:</p>\n<blockquote>\n<p>A program may add a template specialization […] only if […] the specialization meets the\nstandard library requirements for the original template.</p>\n</blockquote>\n<p>So what are the exact rules on <code class=\"language-text\">default_delete::operator()</code>? Section 20.8.1.1.2, item 3 reads:</p>\n<blockquote>\n<p>Effects: calls delete on ptr.</p>\n</blockquote>\n<p>In other words: specializing <code class=\"language-text\">default_delete</code> is allowed only if the effects of the specialization are to call <code class=\"language-text\">delete</code> on the pointer.</p>\n<p>➥ Thus our specialization does not meet the requirements for <code class=\"language-text\">default_delete::operator()</code>,\nand is <strong>not allowed</strong> by the C++ standard.</p>\n<p>But we are on the right track.</p>\n<p>Instead of hijacking <code class=\"language-text\">std::default_delete</code>, let's <b>create our own</b>.</p>\n<h2 id=\"zero-cost-deleter\">Zero-cost deleter</h2>\n<p>As the existence of <code class=\"language-text\">default_delete</code> hints, the Deleter argument of <code class=\"language-text\">unique_ptr</code> actually\nallows <strong>function objects</strong>. That is, objects that behave as functions (supporting <code class=\"language-text\">operator()</code>).</p>\n<p>This is exaclty what we will do. We use an empty object with just <code class=\"language-text\">operator()</code>:</p>\n<div class=\"figure-wrapper\"><figure id=\"fig-8\"><div class=\"gatsby-highlight\" data-language=\"cpp\"><pre class=\"language-cpp\"><code class=\"language-cpp\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">external_api_deleter</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">void</span> <span class=\"token keyword\">operator</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">(</span>external_api <span class=\"token operator\">*</span> ptr<span class=\"token punctuation\">)</span> <span class=\"token keyword\">const</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">close_my_api</span><span class=\"token punctuation\">(</span>ptr<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span> <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">using</span> api_ptr <span class=\"token operator\">=</span> std<span class=\"token double-colon punctuation\">::</span>unique_ptr<span class=\"token operator\">&lt;</span>external_api<span class=\"token punctuation\">,</span> external_api_deleter<span class=\"token operator\">></span><span class=\"token punctuation\">;</span>\n\n<span class=\"token keyword\">void</span> <span class=\"token function\">do_something</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">auto</span> api <span class=\"token operator\">=</span> <span class=\"token function\">api_ptr</span><span class=\"token punctuation\">(</span><span class=\"token function\">open_my_api</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    cout <span class=\"token operator\">&lt;&lt;</span><span class=\"token string\">\"    -> pointer size is \"</span> <span class=\"token operator\">&lt;&lt;</span><span class=\"token keyword\">sizeof</span><span class=\"token punctuation\">(</span>api<span class=\"token punctuation\">)</span> <span class=\"token operator\">&lt;&lt;</span>endl<span class=\"token punctuation\">;</span>\n    <span class=\"token comment\">// do things using api</span>\n<span class=\"token punctuation\">}</span></code></pre></div><div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">$ ./correct\nExternal C api 0x561c3a3fce70 opened\n    -> pointer size is 8\nExternal C api 0x561c3a3fce70 closed</code></pre></div><figcaption><div class=\"figcaption-wrapper\">Custom deleter as a default-constructible functor.</div></figcaption></figure></div>\n<p><b>Success!</b></p>\n<p>Our <code class=\"language-text\">unique_ptr</code> calls <code class=\"language-text\">close_my_api()</code> correctly. Yet it does not store the pointer to it,\nas we can see from the final pointer size being 8 bytes.</p>\n<p>What actually happens is that an instance of <code class=\"language-text\">external_api_deleter</code> is default-constructed\nand stored. As it is an empty class, this has perfect performance (this generates no\nassembly instruction). And thanks to\n<a href=\"https://en.cppreference.com/w/cpp/language/ebo\" class=\"external\" rel=\"external noopener noreferrer\">empty base optimisation</a>, is uses no storage\nat all.<sup id=\"fnref-2\"><a href=\"#fn-2\" class=\"footnote-ref\">2</a></sup></p>\n<p>There we have it. Legal, correct, <b>zero-cost deleter</b> for <code class=\"language-text\">unique_ptr</code>.</p>\n<br/>\n<p>I hope you enjoyed this post. I pushed the code of the examples\n<a href=\"https://github.com/solid-abstractions/software/tree/master/deleters\" class=\"external\" rel=\"external noopener noreferrer\">on github</a>. Have a\nquestion? See an error? Send me a <a href=\"/about\" class=\"internal\">message</a>!</p>\n<div class=\"footnotes\">\n<hr>\n<ol>\n<li id=\"fn-1\">\n<p>In addition, such a <code class=\"language-text\">unique_ptr</code> cannot be default-constructed, because the deleter\npointer must always be provided. This can be a minor inconvenience, or have a big impact.\nFor instance it prevents using map's <code class=\"language-text\">operator[]</code>.</p>\n<a href=\"#fnref-1\" class=\"footnote-backref\">↩</a>\n</li>\n<li id=\"fn-2\">\n<p>This is not guaranteed, but true in practice on all systems I tested this one.</p>\n<a href=\"#fnref-2\" class=\"footnote-backref\">↩</a>\n</li>\n</ol>\n</div>","fields":{"isPage":false,"slug":"/2019/zero-cost-unique_ptr"},"frontmatter":{"title":"Zero-cost unique_ptr deleters","classname":null,"date":"2019-03-05T00:00:00.000Z","formattedDate":"March 05, 2019","isoDate":"2019-03-05T00:00:00+00:00"},"headings":[{"value":"Why a custom deleter?","depth":1},{"value":"Failed attempts","depth":1},{"value":"Working naive approach","depth":2},{"value":"Hijacking default_delete","depth":2},{"value":"Zero-cost deleter","depth":1}],"image":null,"series":{"name":"software","fullName":"software engineering","fields":{"slug":"/software"}},"tags":[{"name":"code","slug":"/tag/code"},{"name":"c++","slug":"/tag/c"}]}},"pageContext":{"series":"software","slug":"/2019/zero-cost-unique_ptr","previous":{"fields":{"slug":"/2019/error-handling-levels"},"frontmatter":{"title":"Error Handling part 2: Abstractions","series":"software"},"tags":[{"name":"code","slug":"/tag/code"}]},"next":{"fields":{"slug":"/2019/error-handling-techniques"},"frontmatter":{"title":"Error Handling part 3: Techniques","series":"software"},"tags":[{"name":"code","slug":"/tag/code"}]},"seriesPrevious":{"fields":{"slug":"/2019/error-handling-levels"},"frontmatter":{"title":"Error Handling part 2: Abstractions","series":"software"},"tags":[{"name":"code","slug":"/tag/code"}]},"seriesNext":{"fields":{"slug":"/2019/error-handling-techniques"},"frontmatter":{"title":"Error Handling part 3: Techniques","series":"software"},"tags":[{"name":"code","slug":"/tag/code"}]}}},
    "staticQueryHashes": ["1733002695","4006707078"]}