{"id":105191,"date":"2021-05-06T07:00:00","date_gmt":"2021-05-06T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=105191"},"modified":"2021-05-06T08:05:54","modified_gmt":"2021-05-06T15:05:54","slug":"20210506-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210506-00\/?p=105191","title":{"rendered":"Is std::exception_ptr nothrow constructible and assignable?"},"content":{"rendered":"<p>When I was writing my <a title=\"A map through the three major coroutine series\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210504-01\/?p=105178\"> series on awaitable signals and coroutine promises<\/a>, I had to investigate a few details of the language specification, like <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20210505-00\/?p=105186\"> why <code>coroutine_<wbr \/>handle::<wbr \/>resume()<\/code> is potentially-throwing<\/a>. Another detail I had to investigate was whether <code>std::<wbr \/>exception_<wbr \/>ptr<\/code> was potentially-throwing in its constructors and assignment operators.<\/p>\n<p>The answer is <i>No<\/i>, but you have to chase through the language specification a bit.<\/p>\n<p>The <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/error\/exception_ptr\"> <code>exception_ptr<\/code><\/a> is introduced in the C++ language specification under <a href=\"https:\/\/timsong-cpp.github.io\/cppwp\/n4659\/propagation\"> <b>[propagation]<\/b><\/a>, and it says that <code>exception_ptr<\/code> is a <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/NullablePointer\"> <i>NullablePointer<\/i><\/a>\u00b9 but otherwise says nothing about exceptions.<\/p>\n<p>Chase through to <a href=\"https:\/\/timsong-cpp.github.io\/cppwp\/n4659\/nullablepointer.requirements\"> <b>[nullablepointer.requirements]<\/b><\/a>, which spells out the various operations that must be supported. <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/NullablePointer\"> It says<\/a>, for example, that the object must satisfy <i>Cpp17CopyConstructible<\/i> (or <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/named_req\/CopyConstructible\"><i>CopyConstructible<\/i><\/a>, as cppreference.com calls it), but if you follow that definition, there is still no mention of exceptions.<\/p>\n<p>But the magic sentence is right there. You just overlooked it.<\/p>\n<p>Back in the definition of <i>NullablePointer<\/i>, <a href=\"https:\/\/timsong-cpp.github.io\/cppwp\/n4659\/nullablepointer.requirements#4\"> it says<\/a>,<\/p>\n<blockquote class=\"q\"><p><span style=\"font-size: 66%;\">4<\/span> No operation which is part of the <i>NullablePointer<\/i> requirements shall exit via an exception.<\/p><\/blockquote>\n<p>So there it is. The <code>exception_ptr<\/code>, or more generally, anything that satisfies <i>NullablePointer<\/i>, is nothrow comparable, constructible, assignable, destructible, swappable, and testable.<\/p>\n<p>\u00b9 Starting in C++20, these requirements have been renamed <i>Cpp17NullablePointer<\/i>, <i>Cpp17CopyConstructible<\/i>, <i>etc<\/i>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Yes, buried in the fine print.<\/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-105191","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Yes, buried in the fine print.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105191","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=105191"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/105191\/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=105191"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=105191"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=105191"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}