{"id":5967,"date":"2020-08-13T10:37:34","date_gmt":"2020-08-13T10:37:34","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/new-attributes-with-c-20\/"},"modified":"2020-08-13T10:37:34","modified_gmt":"2020-08-13T10:37:34","slug":"new-attributes-with-c-20","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/new-attributes-with-c-20\/","title":{"rendered":"New Attributes with C++20"},"content":{"rendered":"<p>With C++20, we got new and improved attributes such as <span style=\"font-family: courier new, courier;\">[[nodiscard(&#8220;reason&#8221;)]]<\/span>, <span style=\"font-family: courier new, courier;\">[[likely]]<\/span>,<span style=\"font-family: courier new, courier;\"> [[unlikely]]<\/span>, and <span style=\"font-family: courier new, courier;\">[[no_unique_address]]<\/span>. In particular, <span style=\"font-family: courier new, courier;\">[[nodiscard(&#8220;reason&#8221;)]]<\/span> allows it to express the intention of your interface way clearer.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5945\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/07\/TimelineCpp20CoreLanguage.png\" alt=\"TimelineCpp20CoreLanguage\" width=\"650\" height=\"249\" style=\"display: block; margin-left: auto; margin-right: auto;\" \/><\/p>\n<p>Attributes allow it to express declaratively the intention of your code.<\/p>\n<h2>New Attributes<\/h2>\n<p>During the writing of this article, I become a big fan of <span style=\"font-family: courier new, courier;\">[[nodiscard(&#8220;reason&#8221;)]]<\/span>. Consequently, I want to start with my favorite.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">[[nodiscard(&#8220;reason&#8221;)]]<\/span><\/h3>\n<p>We have <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span> already since C++17. C++20 added the possibility to add a message to the attribute. Unfortunately, I ignored <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span> in the last few years. Let me present it now. Imagine, I have the following program.<\/p>\n<p>&nbsp;<\/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;\">\/\/ withoutNodiscard.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType {\r\n\r\n     MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>) {}\r\n\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\nT<span style=\"color: #555555;\">*<\/span> create(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args)...);\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">ErrorCode<\/span> {\r\n    Okay,\r\n    Warning,\r\n    Critical,\r\n    Fatal\r\n};\r\n\r\nErrorCode <span style=\"color: #cc00ff;\">errorProneFunction<\/span>() { <span style=\"color: #006699; font-weight: bold;\">return<\/span> ErrorCode<span style=\"color: #555555;\">::<\/span>Fatal; }\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: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> val <span style=\"color: #555555;\">=<\/span> create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> val;\r\n\r\n    create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n    errorProneFunction();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n    MyType(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n} \r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Thanks to perfect forwarding and parameter packs, the factory function <span style=\"font-family: 'courier new', courier;\">create<\/span> can call any constructor and return a heap-allocated object.<\/p>\n<p>The program has many issues. First, line (1) has a memory leak because the heap created <span style=\"font-family: courier new, courier;\">int<\/span> is never destroyed. Second, the error code of the function <span style=\"font-family: courier new, courier;\">errorPronceFunction<\/span> (2) is not checked. Last, the constructor call<span style=\"font-family: courier new, courier;\"> MyType(5, true)<\/span> creates a temporary, which is created and immediately destroyed. This is at least a waste of resources. Now,<span style=\"font-family: courier new, courier;\"> [[nodiscard]]<\/span> comes into play.<\/p>\n<p style=\"padding-left: 30px;\"><span style=\"font-family: Courier New, Courier, monospace;\">[[nodiscard]] <\/span>can be used in a function, enumeration, or class declaration. If you discard the return value from a function declared as nodiscard, the compiler should issue a warning. The same holds for a function returning by copy an enumeration or a class declared as <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span>. A cast-to-void should not emit a warning.<\/p>\n<p>Let me see what this means. In the following example, I use the C++17 syntax of the attribute <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span>.<\/p>\n<p>&nbsp;<\/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;\">\/\/ nodiscard.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType {\r\n\r\n     MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>) {}\r\n\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n[[nodiscard]]\r\nT<span style=\"color: #555555;\">*<\/span> create(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args)...);\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> [[<span>nodiscard<\/span>]] ErrorCode {\r\n    Okay,\r\n    Warning,\r\n    Critical,\r\n    Fatal\r\n};\r\n\r\nErrorCode <span style=\"color: #cc00ff;\">errorProneFunction<\/span>() { <span style=\"color: #006699; font-weight: bold;\">return<\/span> ErrorCode<span style=\"color: #555555;\">::<\/span>Fatal; }\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: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> val <span style=\"color: #555555;\">=<\/span> create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> val;\r\n\r\n    create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n    errorProneFunction();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n    MyType(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The factory function <span style=\"font-family: courier new, courier;\">create<\/span> and the enum <span style=\"font-family: courier new, courier;\">ErrorCode<\/span> is declared as<span style=\"font-family: courier new, courier;\"> [[nodiscard]]<\/span>. Consequently, calls (1) and (2) create a warning.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5964\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscard.png\" alt=\"nodiscard\" width=\"650\" height=\"188\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscard.png 1521w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscard-300x87.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscard-1024x296.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscard-768x222.png 768w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Way better, but the program still has a few issues.&nbsp; <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span> cannot be used for functions such as a constructor returning nothing. Therefore, the temporary <span style=\"font-family: courier new, courier;\">MyType(5, true)<\/span> is still created without warning. Second, the error messages are too general. As a user of the functions, I want a reason why discarding the result is an issue.<\/p>\n<p>Both issues can be solved with C++20. Constructors can be declared as <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span>, and the warning could have additional information.<\/p>\n<p>&nbsp;<\/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;\">\/\/ nodiscardString.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;utility&gt;<\/span>\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> MyType {\r\n\r\n     [[nodiscard(<span style=\"color: #cc3300;\">\"Implicit destroying of temporary MyInt.\"<\/span>)]] MyType(<span style=\"color: #007788; font-weight: bold;\">int<\/span>, <span style=\"color: #007788; font-weight: bold;\">bool<\/span>) {}\r\n\r\n};\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">template<\/span> <span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #006699; font-weight: bold;\">typename<\/span> T, <span style=\"color: #006699; font-weight: bold;\">typename<\/span> ... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n[[nodiscard(<span style=\"color: #cc3300;\">\"You have a memory leak.\"<\/span>)]]\r\nT<span style=\"color: #555555;\">*<\/span> create(Args<span style=\"color: #555555;\">&amp;&amp;<\/span> ... args){\r\n  <span style=\"color: #006699; font-weight: bold;\">return<\/span> <span style=\"color: #006699; font-weight: bold;\">new<\/span> T(std<span style=\"color: #555555;\">::<\/span>forward<span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>(args)...);\r\n}\r\n\r\n<span style=\"color: #006699; font-weight: bold;\">enum<\/span> <span style=\"color: #006699; font-weight: bold;\">class <\/span>[[nodiscard(<span style=\"color: #cc3300;\">\"Don't ignore the error code.\"<\/span>)]] ErrorCode {\r\n    Okay,\r\n    Warning,\r\n    Critical,\r\n    Fatal\r\n};\r\n\r\nErrorCode <span style=\"color: #cc00ff;\">errorProneFunction<\/span>() { <span style=\"color: #006699; font-weight: bold;\">return<\/span> ErrorCode<span style=\"color: #555555;\">::<\/span>Fatal; }\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: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">*<\/span> val <span style=\"color: #555555;\">=<\/span> create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);\r\n    <span style=\"color: #006699; font-weight: bold;\">delete<\/span> val;\r\n\r\n    create<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">5<\/span>);         <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n\r\n    errorProneFunction();   <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n    \r\n    MyType(<span style=\"color: #ff6600;\">5<\/span>, <span style=\"color: #336666;\">true<\/span>);        <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Now, the user of the functions gets a specific message. Here is the output of the Microsoft compiler.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5965\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2.png\" alt=\"nodiscardString2\" width=\"650\" height=\"231\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2.png 3014w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2-300x107.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2-1024x364.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2-768x273.png 768w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2-1536x545.png 1536w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/nodiscardString2-2048x727.png 2048w\" sizes=\"auto, (max-width: 650px) 100vw, 650px\" \/><\/p>\n<p>By the way, many existing functions in C++ could benefit from the<span style=\"font-family: courier new, courier;\"> [[nodiscard]]<\/span> attribute. For example, when you don&#8217;t use the return value of <span style=\"font-family: courier new, courier;\">std::asnyc,<\/span> an asynchronously meant <span style=\"font-family: courier new, courier;\">std::async<\/span> call becomes implicitly synchronous. What should run in a separate thread behaves as a blocking function call. Read more about the counterintuitive behavior of <span style=\"font-family: courier new, courier;\">std::async<\/span> in my blog &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/the-special-futures\">The Special Futures<\/a>&#8220;.<\/p>\n<p>While studying the<span style=\"font-family: courier new, courier;\"> [[nodiscard]]<\/span> syntax on <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/thread\/async\">cppreference.com<\/a>, I noticed that the overload of <span style=\"font-family: courier new, courier;\">std::async<\/span> changed with C++20. Here is one:<\/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: #006699; font-weight: bold;\">template<\/span><span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #006699; font-weight: bold;\">class<\/span> <span style=\"color: #00aa88; font-weight: bold;\">Function<\/span>, class... Args<span style=\"color: #555555;\">&gt;<\/span>\r\n[[nodiscard]]\r\nstd<span style=\"color: #555555;\">::<\/span>future<span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">invoke_result_t<\/span><span style=\"color: #555555;\">&lt;<\/span>std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">decay_t<\/span><span style=\"color: #555555;\">&lt;<\/span>Function<span style=\"color: #555555;\">&gt;<\/span>,\r\n                                 std<span style=\"color: #555555;\">::<\/span><span style=\"color: #007788; font-weight: bold;\">decay_t<\/span><span style=\"color: #555555;\">&lt;<\/span>Args<span style=\"color: #555555;\">&gt;<\/span>...<span style=\"color: #555555;\">&gt;&gt;<\/span>\r\n    async( Function<span style=\"color: #555555;\">&amp;&amp;<\/span> f, Args<span style=\"color: #555555;\">&amp;&amp;<\/span>... args );\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p><span style=\"font-family: courier new, courier;\">std::future<\/span> as return-type of the promise<span style=\"font-family: courier new, courier;\"> std::async<\/span> is declared as <span style=\"font-family: courier new, courier;\">[[nodiscard]]<\/span>.<\/p>\n<p>The following two attributes <span style=\"font-family: courier new, courier;\">[[likely]]<\/span> and<span style=\"font-family: courier new, courier;\"> [[unlikely]]<\/span>, are about optimization.<\/p>\n<\/p>\n<h3><span style=\"font-family: courier new, courier;\">[[likely]]<\/span> and <span style=\"font-family: courier new, courier;\">[[unlikely]]<\/span><\/h3>\n<p>The proposal P0479R5 for likely and unlikely attributes is the shortest proposal I know of. To give you an idea, this is an interesting note to the proposal. &#8220;<em>The use of the <span class=\"mono\"><strong>likely<\/strong><\/span> attribute is intended to allow implementations to optimize for the case where paths of execution including it are arbitrarily more likely than any alternative path of execution that does not include such an attribute on a statement or label. The use of the <span class=\"mono\"><strong>unlikely<\/strong><\/span> attribute is intended to allow implementations to optimize for the case where paths of execution including it are arbitrarily more unlikely than any alternative path of execution that does not include such an attribute on a statement or label. A path of execution includes a label if and only if it contains a jump to that label. Excessive usage of either of these attributes is liable to result in performance degradation<\/em>.&#8221;<\/p>\n<p>To make it short, both attributes allow it to give the optimizer a hint about which path of execution is more or less likely.<\/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: #006699; font-weight: bold;\">for<\/span>(<span style=\"color: #007788; font-weight: bold;\">size_t<\/span> i<span style=\"color: #555555;\">=<\/span><span style=\"color: #ff6600;\">0<\/span>; i <span style=\"color: #555555;\">&lt;<\/span> v.size(); <span style=\"color: #555555;\">++<\/span>i){\r\n    <span style=\"color: #006699; font-weight: bold;\">if<\/span> (v[i] <span style=\"color: #555555;\">&lt;<\/span> <span style=\"color: #ff6600;\">0<\/span>) [[likely]] sum <span style=\"color: #555555;\">-=<\/span> sqrt(<span style=\"color: #555555;\">-<\/span>v[i]);\r\n    <span style=\"color: #006699; font-weight: bold;\">else<\/span> sum <span style=\"color: #555555;\">+=<\/span> sqrt(v[i]);\r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>&nbsp;The story with optimization goes on with the new attribute <span style=\"font-family: courier new, courier;\">[[no_unique_address]<\/span>]. This time the optimization addresses space.<\/p>\n<h3><span style=\"font-family: courier new, courier;\">[[no_unique_address]]<\/span><\/h3>\n<p><span style=\"font-family: 'courier new', courier;\">[[no_unique_address]]<\/span> expresses that this data member of a class&nbsp;<span style=\"color: #000000; font-family: 'DejaVu Sans', arial, sans-serif; font-size: 12.8px; font-style: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; background-color: #ffffff; float: none;\">need not have an address distinct from all other non-static data members of its class. Consequently, if the member has an empty type, the compiler can optimize it to occupy no memory.<\/span><\/p>\n<p>The following program exemplifies the usage of the new attribute.<\/p>\n<p>&nbsp;<\/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;\">\/\/ uniqueAddress.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> Empty {}; \r\n \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> NoUniqueAddress {\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> d{};\r\n    Empty e{};\r\n};\r\n \r\n<span style=\"color: #006699; font-weight: bold;\">struct<\/span> UniqueAddress {\r\n    <span style=\"color: #007788; font-weight: bold;\">int<\/span> d{};\r\n    [[no_unique_address]] Empty e{};                                     <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n};\r\n \r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>() {\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>boolalpha;\r\n\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"sizeof(int) == sizeof(NoUniqueAddress): \"<\/span>              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> (<span style=\"color: #006699; font-weight: bold;\">sizeof<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) <span style=\"color: #555555;\">==<\/span> <span style=\"color: #006699; font-weight: bold;\">sizeof<\/span>(NoUniqueAddress)) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"sizeof(int) == sizeof(UniqueAddress): \"<\/span>                <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n              <span style=\"color: #555555;\">&lt;&lt;<\/span> (<span style=\"color: #006699; font-weight: bold;\">sizeof<\/span>(<span style=\"color: #007788; font-weight: bold;\">int<\/span>) <span style=\"color: #555555;\">==<\/span> <span style=\"color: #006699; font-weight: bold;\">sizeof<\/span>(UniqueAddress)) <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    NoUniqueAddress NoUnique;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"&amp;NoUnique.d: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  <span style=\"color: #555555;\">&amp;<\/span>NoUnique.d <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"&amp;NoUnique.e: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  <span style=\"color: #555555;\">&amp;<\/span>NoUnique.e <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;           <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n    \r\n    UniqueAddress unique;\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"&amp;unique.d: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  <span style=\"color: #555555;\">&amp;<\/span>unique.d <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n    std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"&amp;unique.e: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span>  <span style=\"color: #555555;\">&amp;<\/span>unique.e <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;               <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n    \r\n    std<span style=\"color: #555555;\">::<\/span>cout <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 class <span style=\"font-family: 'courier new', courier;\">NoUniqueAddress<\/span> has another size as an <span style=\"font-family: 'courier new', courier;\">int<\/span> (2) but not the class <span style=\"font-family: 'courier new', courier;\">UniqueAddress<\/span> (3). The members <span style=\"font-family: 'courier new', courier;\">d<\/span> and <span style=\"font-family: 'courier new', courier;\">e<\/span> of <span style=\"font-family: 'courier new', courier;\">NoUniqueAddress<\/span> (4) have different addresses but not the members of the class <span style=\"font-family: 'courier new', courier;\">UniqueAddress (5).<\/span><\/p>\n<div>&nbsp;<\/div>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5966\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/uniqueAddress.png\" alt=\"uniqueAddress\" width=\"524\" height=\"230\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/uniqueAddress.png 524w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2020\/08\/uniqueAddress-300x132.png 300w\" sizes=\"auto, (max-width: 524px) 100vw, 524px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>The <span style=\"font-family: 'courier new', courier;\">volatile<\/span> qualifier is one of the darkest corners in C++. Consequently, most of <span style=\"font-family: 'courier new', courier;\">volatile<\/span> has been deprecated in C++20.<\/p>\n<div>&nbsp;<\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>With C++20, we got new and improved attributes such as [[nodiscard(&#8220;reason&#8221;)]], [[likely]], [[unlikely]], and [[no_unique_address]]. In particular, [[nodiscard(&#8220;reason&#8221;)]] allows it to express the intention of your interface way clearer.<\/p>\n","protected":false},"author":21,"featured_media":5945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[375],"tags":[],"class_list":["post-5967","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-c-20"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5967","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=5967"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5967\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5945"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5967"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5967"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5967"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}