{"id":107330,"date":"2022-10-28T07:00:00","date_gmt":"2022-10-28T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=107330"},"modified":"2022-10-27T19:18:09","modified_gmt":"2022-10-28T02:18:09","slug":"20221028-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20221028-00\/?p=107330","title":{"rendered":"Setting properties in C++\/WinRT is done by a function call, but you need to call the function the right way"},"content":{"rendered":"<p>For people transitioning to C++\/WinRT from other languages, a common beginner mistake is setting properties incorrectly. Here are the ways of accessing a Windows Runtime property in various languages.<\/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>Read a property<\/th>\n<th>Write a property<\/th>\n<\/tr>\n<tr>\n<td>C#<\/td>\n<td><code>oldValue = o.ActiveWidget;<\/code><\/td>\n<td><code>o.ActiveWidget = newValue;<\/code><\/td>\n<\/tr>\n<tr>\n<td>VB<\/td>\n<td><code>oldValue = o.ActiveWidget<\/code><\/td>\n<td><code>o.ActiveWidget = newValue<\/code><\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td><code>oldValue = o.activeWidget;<\/code><\/td>\n<td><code>o.activeWidget = newValue;<\/code><\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td><code>old_value = o.active_widget<\/code><\/td>\n<td><code>o.active_widget = new_value<\/code><\/td>\n<\/tr>\n<tr>\n<td>C++\/CX<\/td>\n<td><code>oldValue = o-&gt;ActiveWidget;<\/code><\/td>\n<td><code>o-&gt;ActiveWidget = newValue;<\/code><\/td>\n<\/tr>\n<tr>\n<td>C++\/WinRT<\/td>\n<td><code>oldValue = o.ActiveWidget();<\/code><\/td>\n<td><code>o.ActiveWidget(newValue);<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Notice the odd one out in the above list.\u00b9 Everybody uses the assignment operator to set a property, except C++\/WinRT, which uses a function call.<\/p>\n<p>If you&#8217;re used to the other languages, you may incorrectly interpret the rule that &#8220;property access is a function call&#8221; People transitioning to C++\/WinRT from other languages are tempted to write<\/p>\n<pre>o.ActiveWidget() = newValue;\r\n<\/pre>\n<p>in a misguided attempt to set the property to a new value. What this actually does is fetch the current value of the property, and then assign the new value to the temporary. It&#8217;s a lot of work with nothing to show for it, and then you scratch your head wondering why the attempt to update the property appears to have been ignored.<\/p>\n<p>I <a href=\"https:\/\/github.com\/microsoft\/cppwinrt\/pull\/825\"> tried to update C++\/WinRT to deny assignment to most types of rvalues<\/a>, rendering the above a compile-time error, but the change <a href=\"https:\/\/github.com\/microsoft\/cppwinrt\/pull\/976\"> had to be reverted for compatibility reasons<\/a>.<\/p>\n<p>There&#8217;s no real value to creating a temporary only to assign a new value to it. You may as well just create the temporary with the desired value, and then use it.<\/p>\n<pre>\/\/ Pointless\r\nDoSomething(o.ActiveWidget() = newValue);\r\n\r\n\/\/ Just do this\r\nDoSomething(Widget(newValue));\r\n\r\n\/\/ Or possibly even just\r\nDoSomething(newValue);\r\n<\/pre>\n<p>\u00b9 Rust\/WinRT also uses function calls to access properties:<\/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>Read a property<\/th>\n<th>Write a property<\/th>\n<\/tr>\n<tr>\n<td>Rust\/WinRT<\/td>\n<td><code>old_value = o.active_widget();<\/code><\/td>\n<td><code>o.set_active_widget(new_value);<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>However, it doesn&#8217;t suffer from the same problem as C++\/WinRT, because Rust disallows assignment to rvalues (known as <i>value expressions<\/i> in Rust-speak).<\/p>\n<pre>\/\/ error E0070: Invalid left-hand side of assignment\r\no.active_widget() = new_value;\r\n<\/pre>\n<p>The problem of assigning to a temporary is peculiar to C++.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The new value is the function parameter.<\/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-107330","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The new value is the function parameter.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107330","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=107330"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/107330\/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=107330"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=107330"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=107330"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}