{"id":103572,"date":"2020-03-19T07:00:00","date_gmt":"2020-03-19T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=103572"},"modified":"2020-03-21T11:49:54","modified_gmt":"2020-03-21T18:49:54","slug":"20200319-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200319-00\/?p=103572","title":{"rendered":"Further refinements to the attempt to create a type-dependent expression that is always false"},"content":{"rendered":"<p>A little while ago, I discussed <a href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200311-00\/?p=103553\/\"> creating a type-dependent expression that is always false<\/a>, and I settled upon this:<\/p>\n<pre>    static_assert(!sizeof(Op*), \"message\");\r\n<\/pre>\n<p>This covers the cases where <code>Op<\/code> is an incomplete type or <code>void<\/code>. <a href=\"https:\/\/twitter.com\/MalwareMinigun\"> Billy O&#8217;Neal<\/a> pointed out to me that there are a few cases where this doesn&#8217;t work.<\/p>\n<p>One case is if <code>Op<\/code> is a reference type. You are not allowed to create pointers to reference types, so the attempt to generate a <code>false<\/code> expression will fail with<\/p>\n<pre>\/\/ MSVC\r\nerror C2528: 'abstract declarator': pointer to reference is illegal\r\n\r\n\/\/ gcc\r\nerror: forming pointer to reference type\r\n\r\n\/\/ clang\r\nerror: 'type name' declared as pointer to a reference\r\n<\/pre>\n<p>This can be repaired by wrapping <code>Op<\/code> in a <code>std::<\/code><code>decay_t<\/code>:<\/p>\n<pre> static_assert(<span style=\"color: blue;\">!sizeof(std::decay_t&lt;Op&gt;*)<\/span>,\r\n               \"Don't know what you are asking me to do.\");\r\n<\/pre>\n<p>But the next part is worse: The <code>Op<\/code> could be an <i>abominable function<\/i>.<\/p>\n<p>I was previously not aware of abominable functions, but upon reading up on them, I&#8217;ve concluded that they are fully deserving of their name. It&#8217;s like hot lava, fatal poison, and supernatural malfeasance all rolled up into one.<\/p>\n<p><a href=\"http:\/\/www.open-std.org\/JTC1\/SC22\/WG21\/docs\/papers\/2015\/p0172r0.html\"> Read up on abominable function types<\/a> and see if you agree.<\/p>\n<p>The only way to win the game with abominable functions is not to play, so let&#8217;s just hand it off to <code>std::void_t<\/code> to be neutralized into a <code>void<\/code>. This also solves the problem with references, since <code>std::void_t<\/code> simply sucks up everything it is given and spits out a <code>void<\/code>.<\/p>\n<p>That leaves us with this:<\/p>\n<pre> static_assert(<span style=\"color: blue;\">!sizeof(std::void_t&lt;Op&gt;*)<\/span>,\r\n               \"Don't know what you are asking me to do.\");\r\n<\/pre>\n<p>At this point, since we know that the only thing that can come out of <code>std::void_t<\/code> is <code>void<\/code> itself, we can tweak the expression to make a false statement a bit more directly:<\/p>\n<pre> static_assert(<span style=\"color: blue;\">std::is_same_v&lt;std::void_t&lt;Op&gt;, int&gt;<\/span>,\r\n               \"Don't know what you are asking me to do.\");\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It still falls down, but for stranger reasons.<\/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-103572","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>It still falls down, but for stranger reasons.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103572","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=103572"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/103572\/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=103572"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=103572"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=103572"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}