Boost C++ Libraries: Ticket #5578: non-mutable local variables in phoenix https://svn.boost.org/trac10/ticket/5578 <p> Phoenix local variables are non-mutable with the test case below. It seems like making a local variable non-mutable in these cases is the wrong thing to do. </p> <p> If you follow my logic: </p> <ul><li>TEST1 -- the local is a ref to the variable i </li><li>TEST2 -- the local is an int containing the value from arg1 or i (and is mutable) </li><li>TEST3 -- I would <em>expect</em> the local to be an into containing the value from arg1... but it doesn't compile because it things the local is immutable </li><li>TEST4 -- I would <em>expect</em> this to work the same as TEST3 </li></ul><div class="wiki-code"><div class="code"><pre><span class="cp">#define TEST3</span> <span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/phoenix/phoenix.hpp&gt;</span><span class="cp"></span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">phoenix</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">phoenix</span><span class="o">::</span><span class="n">arg_names</span><span class="p">;</span> <span class="k">using</span> <span class="k">namespace</span> <span class="n">boost</span><span class="o">::</span><span class="n">phoenix</span><span class="o">::</span><span class="n">local_names</span><span class="p">;</span> <span class="cp">#ifdef TEST1</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;TEST1&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cm">/**</span> <span class="cm"> * This will print 41 41.</span> <span class="cm"> * _a is a local variable that is a reference to i. This is a little surprising</span> <span class="cm"> * at first but not too bad. We can deal with it.</span> <span class="cm"> */</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span> <span class="n">let</span><span class="p">(</span> <span class="n">_a</span> <span class="o">=</span> <span class="n">arg1</span> <span class="p">)</span> <span class="p">[</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">--</span><span class="n">_a</span> <span class="p">](</span><span class="n">i</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39; &#39;</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cp">#endif </span><span class="c1">// TEST1</span> <span class="cp">#ifdef TEST2</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;TEST2&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cm">/**</span> <span class="cm"> * This will print 41 42.</span> <span class="cm"> * _a is a local variable initialized with the value of arg1. Makes sense</span> <span class="cm"> */</span> <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">42</span><span class="p">;</span> <span class="n">let</span><span class="p">(</span> <span class="n">_a</span> <span class="o">=</span> <span class="n">val</span><span class="p">(</span><span class="n">arg1</span><span class="p">)</span> <span class="p">)</span> <span class="p">[</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">--</span><span class="n">_a</span> <span class="p">](</span><span class="n">i</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="sc">&#39; &#39;</span> <span class="o">&lt;&lt;</span> <span class="n">i</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cp">#endif </span><span class="c1">// TEST2</span> <span class="cp">#ifdef TEST3</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;TEST3&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cm">/**</span> <span class="cm"> * This wont compile because _a is not mutable. This is not only</span> <span class="cm"> * surprising but makes local scoped variables have very limited use.</span> <span class="cm"> */</span> <span class="n">let</span><span class="p">(</span> <span class="n">_a</span> <span class="o">=</span> <span class="n">val</span><span class="p">(</span><span class="n">arg1</span><span class="p">)</span> <span class="p">)</span> <span class="p">[</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">--</span><span class="n">_a</span> <span class="p">](</span><span class="mi">42</span><span class="p">);</span> <span class="cp">#endif </span><span class="c1">// TEST3</span> <span class="cp">#ifdef TEST4</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;TEST4&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> <span class="cm">/**</span> <span class="cm"> * This fails for the same reason... I would expect it to work also.</span> <span class="cm"> */</span> <span class="n">let</span><span class="p">(</span> <span class="n">_a</span> <span class="o">=</span> <span class="n">val</span><span class="p">(</span><span class="mi">42</span><span class="p">)</span> <span class="p">)</span> <span class="p">[</span> <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="o">--</span><span class="n">_a</span> <span class="p">]();</span> <span class="cp">#endif </span><span class="c1">// TEST4</span> <span class="k">return</span> <span class="mi">1</span><span class="p">;</span> <span class="p">}</span> </pre></div></div> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5578 Trac 1.4.3 anonymous Sat, 28 May 2011 01:05:02 GMT <link>https://svn.boost.org/trac10/ticket/5578#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5578#comment:1</guid> <description> <p> Everything is working as expected. </p> <p> Test 1: --_a ==&gt; result is 41, will print 41 Because it is captured by reference, it will have a side effect on i </p> <p> Test 2: i is captured by value, it will be decremented, but this change won't be "noticed" by the value-captured i. Correct behavior. </p> <p> Test 3 and Test 4: They actually compile and return the expected result </p> <p> These changes have been made just recently (a few hours ago), you might update your working copy. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Thomas Heller</dc:creator> <pubDate>Sat, 28 May 2011 01:16:36 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5578#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5578#comment:2</guid> <description> <p> the previous comment was by me ... login fail. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Thomas Heller</dc:creator> <pubDate>Sat, 28 May 2011 01:16:53 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/5578#comment:3 https://svn.boost.org/trac10/ticket/5578#comment:3 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">worksforme</span> </li> </ul> Ticket Michael Caisse Sat, 28 May 2011 03:05:51 GMT <link>https://svn.boost.org/trac10/ticket/5578#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5578#comment:4</guid> <description> <p> Hi Thomas - </p> <p> Yes, Test1 and Test2 worked "correctly". </p> <p> Test3 and Test4 were not compiling with the version of trunk I was using. I have updated and it is working as expected now. </p> <p> Thanks for the fast turn around! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Thomas Heller</dc:creator> <pubDate>Wed, 29 Jun 2011 10:21:48 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/5578#comment:5 https://svn.boost.org/trac10/ticket/5578#comment:5 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.47.0</span> </li> </ul> Ticket