Boost C++ Libraries: Ticket #13561: boost::detail::nullary_function causes stack overflow when copied https://svn.boost.org/trac10/ticket/13561 <p> Hi, </p> <p> It seems as though boost::detail::nullary_function implement a perfect forwarding constructor incorrectly, which causes a stack overflow: </p> <p> Here is a simple example: </p> <div class="wiki-code"><div class="code"><pre><span class="cp">#include</span> <span class="cpf">&lt;boost/thread/detail/nullary_function.hpp&gt;</span><span class="cp"></span> <span class="cp">#include</span> <span class="cpf">&lt;boost/system/detail/error_code.ipp&gt;</span><span class="cp"></span> <span class="kt">int</span> <span class="nf">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="n">boost</span><span class="o">::</span><span class="n">detail</span><span class="o">::</span><span class="n">nullary_function</span><span class="o">&lt;</span><span class="kt">void</span> <span class="p">()</span><span class="o">&gt;</span> <span class="n">f1</span><span class="p">;</span> <span class="k">auto</span> <span class="n">f2</span> <span class="o">=</span> <span class="n">f1</span><span class="p">;</span> <span class="p">}</span> </pre></div></div><p> This ends up invoking nullary_function.hpp:81 which keeps invoking iself recursively, resulting in a stack overflow. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/13561 Trac 1.4.3 jeff Wed, 06 Jun 2018 23:36:09 GMT <link>https://svn.boost.org/trac10/ticket/13561#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13561#comment:1</guid> <description> <p> From the history, it seems the bug in nullary_function has been there for a couple of years. A simple way to fix is to add another overload </p> <pre class="wiki"> nullary_function(nullary_function&amp; other) BOOST_NOEXCEPT : impl(other.impl) { } </pre><p> Or to add enable_if to </p> <pre class="wiki"> template&lt;typename F, typename = typename boost::enable_if&lt;!boost::is_same&lt;typename decay&lt;F&gt;::type, this_type&gt;::value&gt;::type&gt; nullary_function(BOOST_THREAD_RV_REF(F) f): impl(new impl_type&lt;typename decay&lt;F&gt;::type&gt;(thread_detail::decay_copy(boost::forward&lt;F&gt;(f)))) {} </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>jeff</dc:creator> <pubDate>Thu, 07 Jun 2018 02:13:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13561#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13561#comment:2</guid> <description> <p> Fix a typo in the second code block: it should be enable_if_c instead of enable_if. also this_type is nullary_function&lt;void()&gt; or nullary_function&lt;R()&gt; (depending on the specialization). </p> <pre class="wiki"> using this_type = nullary_function&lt;void()&gt;; template&lt;typename F, typename = typename boost::enable_if_c&lt;!boost::is_same&lt;typename decay&lt;F&gt;::type, this_type&gt;::value&gt;::type&gt; nullary_function(BOOST_THREAD_RV_REF(F) f): impl(new impl_type&lt;typename decay&lt;F&gt;::type&gt;(thread_detail::decay_copy(boost::forward&lt;F&gt;(f)))) {} </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 07 Aug 2018 07:01:04 GMT</pubDate> <title>owner, status changed https://svn.boost.org/trac10/ticket/13561#comment:3 https://svn.boost.org/trac10/ticket/13561#comment:3 <ul> <li><strong>owner</strong> changed from <span class="trac-author">Anthony Williams</span> to <span class="trac-author">viboes</span> </li> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> Thanks for the report. I'll try to fix it soon but a PR on github would help as well. </p> Ticket viboes Tue, 07 Aug 2018 08:45:58 GMT <link>https://svn.boost.org/trac10/ticket/13561#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13561#comment:4</guid> <description> <p> I've some trouble identifying where there is recursion </p> <pre class="wiki"> template&lt;typename F&gt; nullary_function(BOOST_THREAD_RV_REF(F) f): impl(new impl_type&lt;typename decay&lt;F&gt;::type&gt;(thread_detail::decay_copy(boost::forward&lt;F&gt;(f)))) {} </pre><p> <code>impl_type</code> is not <code>nullary_function</code>, isn't it? Could you clarify? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 07 Aug 2018 08:50:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/13561#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/13561#comment:5</guid> <description> <p> Oh, I believe I see it now. </p> <p> The problem is on the open overloads </p> <pre class="wiki">#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES template&lt;typename F&gt; explicit nullary_function(F&amp; f); #endif template&lt;typename F&gt; nullary_function(BOOST_THREAD_RV_REF(F) f); </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>viboes</dc:creator> <pubDate>Tue, 07 Aug 2018 12:07:51 GMT</pubDate> <title>milestone changed https://svn.boost.org/trac10/ticket/13561#comment:6 https://svn.boost.org/trac10/ticket/13561#comment:6 <ul> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.69</span> </li> </ul> <p> <a class="ext-link" href="https://github.com/boostorg/thread/commit/d8d549cf3e01fe74779cd421d88d7079c3a25b49"><span class="icon">​</span>https://github.com/boostorg/thread/commit/d8d549cf3e01fe74779cd421d88d7079c3a25b49</a> </p> Ticket viboes Tue, 11 Sep 2018 21:32:04 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/13561#comment:7 https://svn.boost.org/trac10/ticket/13561#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">assigned</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> </ul> <p> Please reopen if you believe the fix is not good enough. </p> Ticket