{"id":104017,"date":"2020-07-29T07:00:00","date_gmt":"2020-07-29T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=104017"},"modified":"2020-07-29T07:42:01","modified_gmt":"2020-07-29T14:42:01","slug":"20200729-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20200729-00\/?p=104017","title":{"rendered":"C++\/WinRT gotcha: Setting properties incorrectly"},"content":{"rendered":"<p>Getting and setting a Windows Runtime property looks like this:<\/p>\n<table class=\"cp3\" style=\"border-collapse: collapse;\" border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n<tbody>\n<tr>\n<th>Language<\/th>\n<th>Getter<\/th>\n<th>Setter<\/th>\n<\/tr>\n<tr>\n<td>C#<\/td>\n<td><tt>v = o.Property;<\/tt><\/td>\n<td><tt>o.Property = 42;<\/tt><\/td>\n<\/tr>\n<tr>\n<td>C++\/CX<\/td>\n<td><tt>v = o-&gt;Property;<\/tt><\/td>\n<td><tt>o-&gt;Property = 42;<\/tt><\/td>\n<\/tr>\n<tr>\n<td>C++\/WinRT<\/td>\n<td><tt>v = o.Property();<\/tt><\/td>\n<td><tt>o.Property(42);<\/tt><\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td><tt>v = o.property;<\/tt><\/td>\n<td><tt>o.property = 42;<\/tt><\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td><tt>v = o.property<\/tt><\/td>\n<td><tt>o.property = 42<\/tt><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Somebody is the odd man out.<\/p>\n<p>All the projections use a simple member access to read a property and a simple assignment statement to set a property, with the exception of C++\/WinRT, which uses a function call in both places.<\/p>\n<p>That&#8217;s because the standard C++ language doesn&#8217;t have &#8220;properties&#8221;, and C++\/WinRT is a projection of the Windows Runtime into standard C++. (C++\/CX gets away with it because it&#8217;s not standard C++.)<\/p>\n<p>If you&#8217;re translating existing code from one of the other languages to C++\/WinRT, you may realize that properties need to change to function calls, but in your haste (or tiredness), you mistakenly convert <code>o.Property = 42<\/code> to<\/p>\n<pre>    o.Property() = 42;\r\n<\/pre>\n<p>Fortunately, this gives you a compiler error because you cannot assign to an integer value.<\/p>\n<p>Unfortunately, if the property has a non-primitive type, you don&#8217;t get an error.<\/p>\n<pre>    o.Name() = L\"Fred\";\r\n    \/\/ oops: Should be o.Name(L\"Fred\");\r\n\r\n    lv.Background() = greenBrush;\r\n    \/\/ oops: Should be lv.Background(greenBrush);\r\n<\/pre>\n<p>That&#8217;s because you are assigning to the temporary object returned by the property getter method, and that temporary object has an assignment operator.<\/p>\n<p>The above code breaks down like this:<\/p>\n<pre>    auto name = o.Name();\r\n    name = L\"Fred\";\r\n    \/\/ destruct temporary \"name\"\r\n\r\n    auto background = lv.Background();\r\n    background = greenBrush;\r\n    \/\/ destruct temporary \"background\"\r\n<\/pre>\n<p>Congratulations, you updated a temporary that was immediately destructed. Total waste of time.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A bit too much search\/replace during porting.<\/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-104017","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>A bit too much search\/replace during porting.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104017","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=104017"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/104017\/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=104017"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=104017"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=104017"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}