{"id":107269,"date":"2022-10-10T07:00:00","date_gmt":"2022-10-10T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107269"},"modified":"2022-10-10T07:17:19","modified_gmt":"2022-10-10T14:17:19","slug":"20221010-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20221010-00\/?p=107269","title":{"rendered":"On the overloading of the address-of operator <CODE>&amp;<\/CODE> in smart pointer classes"},"content":{"rendered":"<p>Many smart pointer classes overload the address-of operator <code>&amp;<\/code> to give you access to the inner raw pointer.<\/p>\n<p>Unfortunately, they disagree on what happens to the object being managed by the smart pointer before you get its raw address.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Library<\/th>\n<th>Existing contents<\/th>\n<\/tr>\n<tr>\n<td>_com_ptr_t<\/td>\n<td>Released<\/td>\n<\/tr>\n<tr>\n<td>ATL (CComPtr)<\/td>\n<td>Must be empty<br \/>\n(will assert in Debug)<\/td>\n<\/tr>\n<tr>\n<td>MFC (IPTR)<\/td>\n<td>Released<\/td>\n<\/tr>\n<tr>\n<td>WRL (ComPtr)<\/td>\n<td>Released<\/td>\n<\/tr>\n<tr>\n<td>wil (com_ptr)<\/td>\n<td>Released<\/td>\n<\/tr>\n<tr>\n<td>C++\/WinRT (com_ptr)<\/td>\n<td>N\/A<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>C++\/WinRT avoids the confusion by simply not having an overloaded <code>operator&amp;<\/code> at all! Not having an overloaded <code>operator&amp;<\/code> also makes it easier to take the address of the smart pointer itself. The <code>put()<\/code> method Releases any managed COM pointer and then returns the address of the raw pointer.<\/p>\n<p>So let&#8217;s finish the table. Let&#8217;s say that <code>sp<\/code> is the name of a variable of the corresponding smart pointer type.<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Library<\/th>\n<th>Release<\/th>\n<th>Don&#8217;t release<\/th>\n<th>Assumes empty<\/th>\n<\/tr>\n<tr>\n<td>_com_ptr_t<\/td>\n<td><code>&amp;sp<\/code><\/td>\n<td><code style=\"font-size: 80%;\">&amp;sp.GetInterfacePtr()<\/code><\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>ATL (CComPtr)<\/td>\n<td>&nbsp;<\/td>\n<td><code>&amp;sp.p<\/code><\/td>\n<td><code>&amp;sp<\/code><\/td>\n<\/tr>\n<tr>\n<td>MFC (IPTR)<\/td>\n<td><code>&amp;sp<\/code><\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>WRL (ComPtr)<\/td>\n<td><code>&amp;sp<\/code><br \/>\n<code style=\"font-size: 80%;\">p.ReleaseAndGetAddressOf()<\/code><\/td>\n<td><code>p.GetAddressOf()<\/code><\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>wil (com_ptr)<\/td>\n<td><code>&amp;sp<\/code><br \/>\n<code>sp.put()<\/code><\/td>\n<td><code>sp.addressof()<\/code><\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>C++\/WinRT (com_ptr)<\/td>\n<td><code>sp.put()<\/code><\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><b>Bonus chatter<\/b>: The possibility of an overloaded <code>operator&amp;<\/code> is one of those special cases you tend to forget about when writing template library code.\u00b9 In general, it&#8217;s not safe to use the <code>&amp;<\/code> operator to get the address of an object of unknown type, because the operator might be overloaded. You have to use <code>std::addressof<\/code>.<\/p>\n<p>\u00b9 Hey, at least it&#8217;s not an <a title=\"Rough edges in the when_all coroutine, part 2: Overloaded comma operator\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200904-00\/?p=104172\"> overloaded comma operator<\/a>. That thing is <i>nasty<\/i>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Different patterns, which means you&#8217;re never sure what you&#8217;re going to get.<\/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-107269","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>Different patterns, which means you&#8217;re never sure what you&#8217;re going to get.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107269","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=107269"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107269\/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=107269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}