Boost C++ Libraries: Ticket #12001: Under C++11, BOOST_TEST() wrong on boost::optional + named-parameter-idiom example https://svn.boost.org/trac10/ticket/12001 <p> The example below shows the <code>BOOST_TEST()</code> assertions failing where they should pass, as the equivalent <code>BOOST_CHECK_EQUAL()</code> assertions do. It looks as though <code>BOOST_TEST()</code> is preventing the named-parameter-idiom setter from changing the <code>optional</code> value from <code>boost::none</code>. </p> <p> Importantly, this code works if compiled without <code>-std=c++11</code>. </p> <p> Compile commands: </p> <pre class="wiki">g++ -std=c++11 -isystem $BOOST_ROOT/include test_test_bug.cpp -L$BOOST_ROOT/lib -lboost_unit_test_framework-mt setenv LD_LIBRARY_PATH $BOOST_ROOT/lib ./a.out -l all </pre><p> Code: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#ifndef BOOST_TEST_DYN_LINK</span> <span class="cp">#define BOOST_TEST_DYN_LINK</span> <span class="cp">#endif</span> <span class="cp">#include</span> <span class="cpf">&lt;boost/test/unit_test.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/optional/optional.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/optional/optional_io.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp"></span> <span class="k">class</span> <span class="nc">my_class</span> <span class="p">{</span> <span class="k">private</span><span class="o">:</span> <span class="n">boost</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="n">num</span><span class="p">;</span> <span class="k">public</span><span class="o">:</span> <span class="n">my_class</span><span class="p">(</span><span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">arg_num</span><span class="p">)</span> <span class="o">:</span> <span class="n">num</span> <span class="p">(</span> <span class="n">arg_num</span> <span class="p">)</span> <span class="p">{}</span> <span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span> <span class="n">get_num</span><span class="p">()</span> <span class="k">const</span> <span class="p">{</span> <span class="k">return</span> <span class="n">num</span><span class="p">;</span> <span class="p">}</span> <span class="k">const</span> <span class="n">my_class</span> <span class="o">&amp;</span> <span class="n">set_num</span><span class="p">(</span><span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">optional</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">arg_num</span><span class="p">)</span> <span class="p">{</span> <span class="n">num</span> <span class="o">=</span> <span class="n">arg_num</span><span class="p">;</span> <span class="k">return</span> <span class="o">*</span><span class="k">this</span><span class="p">;</span> <span class="p">}</span> <span class="p">};</span> <span class="c1">// Simple stream insertion operator</span> <span class="n">std</span><span class="o">::</span><span class="n">ostream</span> <span class="o">&amp;</span> <span class="k">operator</span><span class="o">&lt;&lt;</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">ostream</span> <span class="o">&amp;</span><span class="n">os</span><span class="p">,</span> <span class="k">const</span> <span class="n">my_class</span> <span class="o">&amp;</span><span class="n">my_obj</span><span class="p">)</span> <span class="p">{</span> <span class="n">os</span> <span class="o">&lt;&lt;</span> <span class="s">&quot;my_class[ &quot;</span> <span class="o">&lt;&lt;</span> <span class="n">my_obj</span><span class="p">.</span><span class="n">get_num</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">&quot; ]&quot;</span><span class="p">;</span> <span class="k">return</span> <span class="n">os</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// Simple equality predicate operator</span> <span class="kt">bool</span> <span class="k">operator</span><span class="o">==</span><span class="p">(</span><span class="k">const</span> <span class="n">my_class</span> <span class="o">&amp;</span><span class="n">my_obj_a</span><span class="p">,</span> <span class="k">const</span> <span class="n">my_class</span> <span class="o">&amp;</span><span class="n">my_obj_b</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="p">(</span> <span class="n">my_obj_a</span><span class="p">.</span><span class="n">get_num</span><span class="p">()</span> <span class="o">==</span> <span class="n">my_obj_b</span><span class="p">.</span><span class="n">get_num</span><span class="p">()</span> <span class="p">);</span> <span class="p">}</span> <span class="n">BOOST_AUTO_TEST_CASE</span><span class="p">(</span><span class="n">my_test</span><span class="p">)</span> <span class="p">{</span> <span class="k">const</span> <span class="n">my_class</span> <span class="n">correct_answer</span><span class="p">(</span> <span class="mi">5</span> <span class="p">);</span> <span class="c1">// These two work as expected</span> <span class="n">BOOST_CHECK_EQUAL</span><span class="p">(</span> <span class="n">my_class</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">none</span> <span class="p">).</span><span class="n">set_num</span><span class="p">(</span> <span class="mi">5</span> <span class="p">),</span> <span class="n">correct_answer</span> <span class="p">);</span> <span class="n">BOOST_CHECK_EQUAL</span><span class="p">(</span> <span class="n">correct_answer</span><span class="p">,</span> <span class="n">my_class</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">none</span> <span class="p">).</span><span class="n">set_num</span><span class="p">(</span> <span class="mi">5</span> <span class="p">)</span> <span class="p">);</span> <span class="c1">// These two fail, evaluating the non-trivial side as &quot;my_class[ -- ]&quot;</span> <span class="n">BOOST_TEST</span> <span class="p">(</span> <span class="n">my_class</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">none</span> <span class="p">).</span><span class="n">set_num</span><span class="p">(</span> <span class="mi">5</span> <span class="p">)</span> <span class="o">==</span> <span class="n">correct_answer</span> <span class="p">);</span> <span class="n">BOOST_TEST</span> <span class="p">(</span> <span class="n">correct_answer</span> <span class="o">==</span> <span class="n">my_class</span><span class="p">(</span> <span class="n">boost</span><span class="o">::</span><span class="n">none</span> <span class="p">).</span><span class="n">set_num</span><span class="p">(</span> <span class="mi">5</span> <span class="p">)</span> <span class="p">);</span> <span class="p">}</span> <span class="kt">bool</span> <span class="n">init_function</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="nb">true</span><span class="p">;</span> <span class="p">}</span> <span class="kt">int</span> <span class="n">main</span><span class="p">(</span> <span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span><span class="o">*</span> <span class="n">argv</span><span class="p">[]</span> <span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="o">::</span><span class="n">boost</span><span class="o">::</span><span class="n">unit_test</span><span class="o">::</span><span class="n">unit_test_main</span><span class="p">(</span> <span class="o">&amp;</span><span class="n">init_function</span><span class="p">,</span> <span class="n">argc</span><span class="p">,</span> <span class="n">argv</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/12001 Trac 1.4.3 Raffi Enficiaud Mon, 23 May 2016 23:20:26 GMT <link>https://svn.boost.org/trac10/ticket/12001#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12001#comment:1</guid> <description> <p> Hi, </p> <p> I cannot reproduce on my setup (OSX, Xcode 6, C++11). I am running on boost 1.61, same example, the 2 BOOST_TEST assertions pass. </p> </description> <category>Ticket</category> </item> <item> <author>Tony Lewis <tonyelewis@…></author> <pubDate>Thu, 26 May 2016 08:26:16 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/12001#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/12001#comment:2</guid> <description> <p> Yes - I've just run the same test on 1.60.0 and 1.61.0 and it showed that the problem has new now been fixed in 1.61.0. </p> <p> Thanks very much. Please feel free to close this ticket as fixed. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Raffi Enficiaud</dc:creator> <pubDate>Thu, 26 May 2016 18:42:19 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/12001#comment:3 https://svn.boost.org/trac10/ticket/12001#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">obsolete</span> </li> </ul> <p> Thanks for the follow up. Closing the ticket now as "obsolete", although it is not clear where the fix comes from. </p> Ticket