{"id":154,"date":"2019-01-03T23:17:22","date_gmt":"2019-01-04T07:17:22","guid":{"rendered":"http:\/\/35.243.195.209\/?p=154"},"modified":"2019-01-03T23:17:46","modified_gmt":"2019-01-04T07:17:46","slug":"lvalues-and-rvalues-in-c","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2019\/01\/03\/lvalues-and-rvalues-in-c\/","title":{"rendered":"Lvalues and Rvalues in C++"},"content":{"rendered":"<h2>Summary<\/h2>\n<p>In this post, I will introduce lvalues and rvalues in C\/C++. But I leave rvalue references and move semantics to the next post.<\/p>\n<h2>Details<\/h2>\n<h3>Definition<\/h3>\n<ol>\n<li>Lvalues: (locator value) represents an object that occupies some unique location in memory (has an address in some scope).<\/li>\n<li>Rvalues: not lvalues.<\/li>\n<\/ol>\n<h3>Important points and examples<\/h3>\n<h4>1. Rvalues can&#8217;t be assigned<\/h4>\n<p>An assignment expects an lvalue as its left operand. See the codes below.<\/p>\n<pre><code class=\"c\">\/\/ lvalue in left operand\nint var;\nvar = 4;\n\n\/\/ rvalue in left operand\n4 = var;       \/\/ ERROR!\n(var + 1) = 4; \/\/ ERROR!\n<\/code><\/pre>\n<h4>2. Function can return lvalue or rvalue<\/h4>\n<p>We can assign value returned by a function. See the codes below.<\/p>\n<pre><code class=\"c\">\/\/ error: lvalue required as left operand of assignment\nint foo() {return 2;}\n\nint main()\n{\n    foo() = 2;\n\n    return 0;\n}\n\n\/\/ good \nint globalvar = 20;\n\nint&amp; foo()\n{\n    return globalvar;\n}\n\nint main()\n{\n    foo() = 10;\n    return 0;\n}\n<\/code><\/pre>\n<p>Actually <code>[]<\/code> in <code>map<\/code> works by using this.<\/p>\n<pre><code class=\"c\">std::map&lt;int, float&gt; mymap;\n\/\/ [] returns a reference that can be assigned to\nmymap[10] = 5.6;\n<\/code><\/pre>\n<h4>3. Unmodifiable lvalues<\/h4>\n<pre><code class=\"c\">const int a = 10; \/\/ 'a' is an lvalue\na = 10;           \/\/ but it can't be assigned!\n<\/code><\/pre>\n<h4>4. Conversions between lvalues and rvalues<\/h4>\n<h5>Implicit lvalues-to-rvalues<\/h5>\n<p>Language constructs operating on object values require rvalues as arguments. All lvalues that aren&#8217;t arrays or functions can be converted to rvalues.<\/p>\n<pre><code class=\"c\">int a = 1;     \/\/ a is an lvalue\nint b = 2;     \/\/ b is an lvalue\nint c = a + b; \/\/ + needs rvalues, so a and b are converted to rvalues\n               \/\/ and an rvalue is returned\n<\/code><\/pre>\n<h5>Explicit lvalues-to-rvalues<\/h5>\n<p>The unary address-of operator <code>&amp;<\/code> takes an lvalue argument and produces an rvalue.<\/p>\n<pre><code class=\"c\">int var = 10;\nint* bad_addr = &amp;(var + 1); \/\/ ERROR: lvalue required as unary '&amp;' operand\nint* addr = &amp;var;           \/\/ OK: var is an lvalue\n&amp;var = 40;                  \/\/ ERROR: lvalue required as left operand\n                            \/\/ of assignment. \n<\/code><\/pre>\n<h5>Explicit rvalues-to-lvalues<\/h5>\n<p>Implicit rvalues-to-lvalues is not possible. But we can use things like unary operator <code>*<\/code> (dereference), which takes an rvalue argument but produces an lvalue as a result.<\/p>\n<pre><code class=\"c\">int arr[] = {1, 2};\nint* p = &amp;arr[0];\n\/\/ good: p + 1 is an rvalue, but *(p + 1) is an lvalue\n*(p + 1) = 10;   \n<\/code><\/pre>\n<h4>5. Lvalue references<\/h4>\n<p><code>&amp;<\/code> can produce &#8220;lvalue references&#8221;. It takes a lvalue and return a lvalue reference. Non-const lvalue references cannot be assigned rvalues, since that would require an invalid rvalue-to-lvalue conversion.<\/p>\n<pre><code class=\"c\">std::string&amp; sref1 = \"Hello world!\"; \/\/ ERROR: invalid initialization of non-const reference of type 'std::string&amp;' from an rvalue of type 'std::string'\nconst std::string&amp; sref2 = \"Hello world!\"; \/\/ good \nstd::string s(\"Hello world!\");\nstd::string&amp; sref3 = s; \/\/ good \n<\/code><\/pre>\n<h2>Reference<\/h2>\n<p><a href=\"https:\/\/eli.thegreenplace.net\/2011\/12\/15\/understanding-lvalues-and-rvalues-in-c-and-c\/\">Eli Bendersky&#8217;s website<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary In this post, I will introduce lvalues and rvalues in C\/C++. But I leave rvalue references and move semantics to the next post. Details Definition Lvalues: (locator value) represents an object that occupies some unique location in memory (has an address in some scope). Rvalues: not lvalues. Important points and examples 1. Rvalues can&#8217;t&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,5],"tags":[],"class_list":["post-154","post","type-post","status-publish","format-standard","hentry","category-c","category-proglang"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/154","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=154"}],"version-history":[{"count":2,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":158,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/154\/revisions\/158"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}