{"id":109592,"date":"2024-03-29T07:00:00","date_gmt":"2024-03-29T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=109592"},"modified":"2024-04-01T10:32:29","modified_gmt":"2024-04-01T17:32:29","slug":"20240329-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20240329-00\/?p=109592","title":{"rendered":"How can I tell C++ that I want to discard a nodiscard value?"},"content":{"rendered":"<p>C++ lets you add the <code>[[nodiscard]]<\/code> attribute to a function return value to indicate that the caller must use the result.<\/p>\n<p>Given the declaration<\/p>\n<pre>[[nodiscard]] int important();\r\n<\/pre>\n<p>simply calling the function and allow the value to be discarded produces diagnostics.<\/p>\n<pre style=\"white-space: pre-wrap;\">void test()\r\n{\r\n    important();\r\n}\r\n\r\nclang: ignoring return value of 'int important()', declared with attribute 'nodiscard' [-Wunused-result]\r\n\r\ngcc: ignoring return value of 'int important()', declared with attribute 'nodiscard' [-Wunused-result]\r\n\r\nmsvc: C4834: discarding return value of function with [[nodiscard]] attribute\r\n<\/pre>\n<p>Explicitly casting to <code>(void)<\/code> works:<\/p>\n<pre>void test()\r\n{\r\n    (void)important();\r\n}\r\n<\/pre>\n<p>Note that this requires a C-style cast. You cannot <span style=\"text-decoration: line-through;\"><code>static_cast<\/code> or<\/span> <code>reinterpret_cast<\/code> to <code>void<\/code>.<\/p>\n<p>Another option is to store the result into a variable which is attributed as unused, and then allowing the variable to go out of scope immediately.<\/p>\n<pre>void test()\r\n{\r\n    { [[maybe_unused]] auto&amp;&amp; unused = important(); }\r\n}\r\n<\/pre>\n<p><a title=\"Make std::ignore a first-class object\" href=\"https:\/\/wg21.link\/p2968r2\"> There is a proposal for C++26 to express the discard with <code>std::<wbr \/>ignore<\/code><\/a>:<\/p>\n<pre>void test()\r\n{\r\n    std::ignore = important();\r\n}\r\n<\/pre>\n<p>Although the ability to assign to <code>std::<wbr \/>ignore<\/code> is not formally required, in practice, you have always been able to do it, and the C++ Core Guidelines <a title=\"Avoid casts\" href=\"https:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#es48-avoid-casts\"> even recommends it<\/a>!<\/p>\n<p>The first is tersest, though it suffers from pedagogical issues discussed in the <code>std::<wbr \/>ignore<\/code> proposal. The third is fairly brief and has the benefit of clarity, but suffers from technically not being allowed (though everybody allows it in practice, so much so that even the C++ Core Guidelines were fooled). The second is most verbose, and the only things it has going for it are the pedagogical avoidance of the <code>(void)<\/code> cast and the language-lawyer avoidance of undocumented use of <code>std::<wbr \/>ignore<\/code>. (In other words, the third option is &#8220;technically&#8221; the most correct, the best kind of correct.)<\/p>\n<p>There&#8217;s an alternate C++26 proposal for expressing the discard with <a title=\"Attribute [[discard]] and attributes on expressions\" href=\"https:\/\/wg21.link\/p2992r0\"> a new <code>[[discard]]<\/code> attribute<\/a>.<\/p>\n<pre>void test()\r\n{\r\n    [[discard(\"reason\")]] important();\r\n}\r\n<\/pre>\n<p><b>Bonus chatter<\/b>: There&#8217;s also a C++26 proposal for <a title=\"A nice placeholder with no name\" href=\"https:\/\/wg21.link\/p2169r4\"> anonymous variables<\/a>. Note that this is not the same as a discarded value, however!<\/p>\n<pre>void test()\r\n{\r\n    auto _ = important();\r\n    something_else();\r\n}\r\n<\/pre>\n<p>This creates an anonymous variable (indicated by <code>_<\/code>) which is <i>not discarded<\/i>. The return value of <code>important()<\/code> is held in the anonymous variable, and that value destructs at the end of the function, after <code>something_else()<\/code> returns.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A variety of tricks, with different degrees of readability and legality.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-109592","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A variety of tricks, with different degrees of readability and legality.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109592","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=109592"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/109592\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=109592"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=109592"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=109592"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}