Boost C++ Libraries: Ticket #5475: [Foreach] rvalue reference binding of temporary ranges https://svn.boost.org/trac10/ticket/5475 <p> C++0x range-based for uses <code>auto &amp;&amp;</code> to bind lvalue/rvalue references to ranges. A good thing is that there is no need to copy ranges anymore. This also allows us to deal with non-copyable rvalue ranges. </p> <p> If a compiler supports rvalue references and auto type deduction (either <code>auto</code> or <code>decltype</code> is OK), Boost.Foreach can be modified to do this. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/5475 Trac 1.4.3 mimomorin@… Fri, 15 Apr 2011 03:38:00 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:1</guid> <description> <p> I will attach patches for <code>boost/foreach.hpp</code> and <code>libs/foreach/test/</code>. </p> </description> <category>Ticket</category> </item> <item> <author>mimomorin@…</author> <pubDate>Fri, 15 Apr 2011 05:37:11 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">test_noncopyable_rvalue.patch</span> </li> </ul> <p> A patch for <code>libs/foreach/test</code> (against trunk) to test iteration over non-copyable and non-movable rvalue ranges. </p> Ticket mimomorin@… Fri, 15 Apr 2011 06:11:04 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:2</guid> <description> <p> Hmm, I cannot attach a patch for <code>foreach.hpp</code>... </p> <p> The patch I made does the following: </p> <p> (Note: contrary to C++0x range-based for, this does not allow mutable iteration over rvalue ranges; Non-const rvalue ranges are bounded to <strong>const</strong> rvalue references.) </p> <ol><li>Adding a configuration macro </li></ol><ul><li>BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING <ul><li>When a compiler supports rvalue references and <code>decltype</code>, this macro is defined and rvalue reference binding is used. </li></ul></li></ul><ol start="2"><li>Adding macros for auto declarations </li></ol><ul><li>BOOST_FOREACH_AUTO_OBJECT(NAME, EXPR) <ul><li>Equivalent to <code>auto NAME = EXPR;</code>. </li></ul></li><li>BOOST_FOREACH_AUTO_REF_REF(NAME, EXPR) <ul><li>Equivalent to <code>auto &amp;&amp; NAME = EXPR;</code>if EXPR is an lvalue. </li><li>Equivalent to <code>auto const &amp;&amp; NAME = EXPR;</code>if EXPR is an rvalue. </li></ul></li></ul><ol start="3"><li>Adding overloaded functions </li></ol><ul><li><code>begin</code> </li><li><code>end</code> <ul><li>For C-strings, this function returns <code>cstr_end_iterator</code>, which is defined as an empty struct. I also overloaded <code>operator !=</code> to support C-strings: <pre class="wiki">template &lt;typename Iterator&gt; inline bool operator !=(Iterator cur, cstr_end_iterator) { return *cur != 0; } </pre></li></ul></li><li><code>rbegin</code> </li><li><code>rend</code> </li></ul><p> All the regression tests ran successfully with the following compilers (both in C++03 and C++0x modes): gcc-4.3.5, gcc-4.4.5, gcc-4.5.2, gcc-4.6.0, clang (TOT). </p> <p> Newly added tests (in <code>test_noncopyable_rvalue.patch</code>) ran successfully in a C++0x mode. </p> </description> <category>Ticket</category> </item> <item> <author>Michel MORIN <mimomorin@…></author> <pubDate>Fri, 15 Apr 2011 07:47:13 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">foreach_cxx0x_v2.patch</span> </li> </ul> <p> A patch for <code>foreach.hpp</code> (against trunk) to bind temporary ranges to const rvalue references. </p> Ticket Michel MORIN <mimomorin@…> Fri, 15 Apr 2011 08:06:23 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:3</guid> <description> <p> All right, succeeded to attach patches! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 20 Sep 2011 02:14:31 GMT</pubDate> <title>status changed https://svn.boost.org/trac10/ticket/5475#comment:4 https://svn.boost.org/trac10/ticket/5475#comment:4 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">assigned</span> </li> </ul> <p> On MSVC 9 and 10, I get: </p> <pre class="wiki">noncopyable_rvalue_const.cpp(60) : error C2248: 'my_container::my_container' : cannot access private member declared in class 'my_container' noncopyable_rvalue_const.cpp(43) : see declaration of 'my_container::my_container' noncopyable_rvalue_const.cpp(19) : see declaration of 'my_container' </pre><p> I can't apply the patch until these issues are resolved. Any ideas? </p> Ticket Michel Morin <mimomorin@…> Tue, 20 Sep 2011 05:52:33 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:5</guid> <description> <p> Thank you for seeing this. </p> <p> On MSVC 9, the following error should emit… </p> <pre class="wiki">#ifndef BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING # error Expected failure : non-copyable rvalues disallowed #else </pre><p> So, the error message you posted is for MSVC 10? </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 20 Sep 2011 13:42:31 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:6</guid> <description> <p> Ah, yes! I was mistakenly using vc10 even in my vc9 environment. I get the proper error with vc9. The above error is with vc10. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Tue, 20 Sep 2011 15:39:08 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:7</guid> <description> <p> OK :) </p> <p> Well, I don't have access to MSVC 10, so could you compile the following codes and tell me what compiler error happens? </p> <p> A.cpp </p> <pre class="wiki">class my_container { public: my_container() {} private: int array_[5]; my_container(my_container const &amp;); my_container &amp;operator =(my_container const &amp;); my_container(my_container &amp;&amp;); my_container &amp;operator =(my_container &amp;&amp;); }; typedef my_container const const_my_container; int main (int argc, char* argv[]) { my_container const &amp;&amp; x = const_my_container(); return 0; } </pre><p> B.cpp </p> <pre class="wiki">class my_container { public: my_container() {} // private: int array_[5]; my_container(my_container const &amp;); my_container &amp;operator =(my_container const &amp;); my_container(my_container &amp;&amp;); my_container &amp;operator =(my_container &amp;&amp;); }; typedef my_container const const_my_container; int main (int argc, char* argv[]) { my_container const &amp;&amp; x = const_my_container(); return 0; } </pre><p> Thanks in advance. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 20 Sep 2011 18:39:27 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:8</guid> <description> <p> A.cpp </p> <pre class="wiki">1&gt;c:\boost\org\trunk\libs\proto\scratch\main.cpp(21): error C2248: 'my_container::my_container' : cannot access private member declared in class 'my_container' 1&gt; c:\boost\org\trunk\libs\proto\scratch\main.cpp(10) : see declaration of 'my_container::my_container' 1&gt; c:\boost\org\trunk\libs\proto\scratch\main.cpp(2) : see declaration of 'my_container' </pre><p> B.cpp No error </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 20 Sep 2011 18:41:41 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:9</guid> <description> <p> P.S. If you have Windows, you have access to MSVC 10: @<a class="ext-link" href="http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express"><span class="icon">​</span>http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express</a> </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Wed, 21 Sep 2011 04:12:04 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:10 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:10</guid> <description> <p> Thanks for doing this. </p> <p> Considering the results, I think the error happens due to the incomplete implementation of C++11 (i.e. <a class="ext-link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#391"><span class="icon">​</span>DR 391</a>) in MSVC 10. The code should compile fine in C++11. </p> <p> The fix for <code>boost/foreach.hpp</code> could be </p> <ol class="upperalpha"><li>Do nothing (BOOST_FOREACH fails with noncopyable rvalues on MSVC 10). </li><li>Revert to the C++03 BOOST_FOREACH on MSVC 10. </li><li>Write a special code for MSVC 10. </li></ol><p> I prefer A, since this does not break anything (noncopyable rvalues cannot be handled by the C++03 BOOST_FOREACH, IIUC). </p> <p> For <code>libs/foreach/test/noncopyable_rvalue_***.hpp</code>, I can change them to pass the tests on MSVC 10 by declaring copy/move ctors and copy/move assignment operators <code>public</code>. But, wouldn't it be better to fail the tests on MSVC 10 to explicitly state that noncopyable rvalues are not supported? </p> <p> P.S. Will try to setup Visual Studio 2010 Express. Thanks! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Thu, 22 Sep 2011 15:36:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:11 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:11</guid> <description> <p> (A) would be fine, I think. We can mark up the expected failures specially. But if you think this is a bug in MSVC, you *must* file a bug here: &lt;<a class="ext-link" href="https://connect.microsoft.com/VisualStudio/"><span class="icon">​</span>https://connect.microsoft.com/VisualStudio/</a>&gt;. (You may need to open an account there to do so.) Use the small repro case you sent me and refer to the relevant part of the standard. Also, double-check that Comeau and GCC accept the code in 0x mode. You can test with Comeau here: &lt;<a class="ext-link" href="http://www.comeaucomputing.com/tryitout/"><span class="icon">​</span>http://www.comeaucomputing.com/tryitout/</a>&gt;. Let me know if you have any problems. Let's get this fixed. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Thu, 22 Sep 2011 18:02:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:12 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:12</guid> <description> <p> I considered just applying this change, msvc10 be damned, but then I realized that I don't know enough about C++11 to say whether the code is well-formed, and Comeau Online rejected your A.cpp source above. Comeau C++11 support is far from perfect, but it makes me uneasy that both msvc and Comeau reject the code. Can you quote the relevant parts of the standard that make A.cpp well-formed? </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 22 Sep 2011 18:19:30 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:13 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:13</guid> <description> <p> I tried Comeau Online and got compilation errors. But it seems that Comeau doesn't recognize rvalue references... </p> <p> The relevant part is 8.5.3 p5: </p> <blockquote> <p> If the initializer expression </p> </blockquote> <ul><li>is an xvalue, class prvalue, array prvalue or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”, or </li><li>has a class type (i.e., T2 is a class type), where T1 is not reference-related to T2, and can be implicitly converted to an xvalue, class prvalue, or function lvalue of type “cv3 T3”, where “cv1 T1” is reference-compatible with “cv3 T3”, </li></ul><blockquote> <p> then <strong>the reference is bound to the value of the initializer expression in the first case</strong> and to the result of the conversion in the second case (or, in either case, to an appropriate base class subobject). In the second case, if the reference is an rvalue reference and the second standard conversion sequence of the user-defined conversion sequence includes an lvalue-to-rvalue conversion, the program is ill-formed. </p> </blockquote> <p> See also links in this answer <a class="ext-link" href="http://stackoverflow.com/questions/1827049/"><span class="icon">​</span>http://stackoverflow.com/questions/1827049/</a> </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 22 Sep 2011 18:39:52 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:14 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:14</guid> <description> <p> The problem in MSVC is that it does the access check of the copy constructor when binding references to rvalues even when the check should not occur. (In C++03, the check is legal.) </p> <p> Here is a minimal code that demonstrates this. </p> <pre class="wiki">class noncopyable { public: noncopyable() {} private: noncopyable(noncopyable const &amp;); }; int main (int argc, char* argv[]) { noncopyable const&amp; x = noncopyable(); return 0; } </pre><p> This code fails to compile on MSVC, but compiles fine on Comeau. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 22 Sep 2011 19:03:28 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:15 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:15</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5475#comment:11" title="Comment 11">eric_niebler</a>: </p> <blockquote class="citation"> <p> But if you think this is a bug in MSVC, you *must* file a bug here: &lt;<a class="ext-link" href="https://connect.microsoft.com/VisualStudio/"><span class="icon">​</span>https://connect.microsoft.com/VisualStudio/</a>&gt;. </p> </blockquote> <p> Done! <a class="ext-link" href="https://connect.microsoft.com/VisualStudio/feedback/details/690244/"><span class="icon">​</span>https://connect.microsoft.com/VisualStudio/feedback/details/690244/</a> </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 22 Sep 2011 19:31:26 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:16 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:16</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/5475#comment:13" title="Comment 13">Michel Morin &lt;mimomorin@…&gt;</a>: </p> <blockquote class="citation"> <p> See also links in this answer <a class="ext-link" href="http://stackoverflow.com/questions/1827049/"><span class="icon">​</span>http://stackoverflow.com/questions/1827049/</a> </p> </blockquote> <p> Specifically, I meant this link <a class="ext-link" href="http://gcc.gnu.org/bugs/#cxx%5Frvalbind"><span class="icon">​</span>http://gcc.gnu.org/bugs/#cxx%5Frvalbind</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Mon, 26 Sep 2011 18:17:10 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:17 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:17</guid> <description> <p> Committed to trunk in <a class="changeset" href="https://svn.boost.org/trac10/changeset/74584" title="support for noncopyable rvalue ranges using C++0x">[74584]</a>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 27 Sep 2011 16:31:33 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/5475#comment:18 https://svn.boost.org/trac10/ticket/5475#comment:18 <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> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/74591" title="merge [74584] from trunk, fixes #5475">[74591]</a>) merge <a class="changeset" href="https://svn.boost.org/trac10/changeset/74584" title="support for noncopyable rvalue ranges using C++0x">[74584]</a> from trunk, fixes <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/5475" title="#5475: Patches: [Foreach] rvalue reference binding of temporary ranges (closed: wontfix)">#5475</a> </p> Ticket Michel Morin <mimomorin@…> Wed, 05 Oct 2011 01:45:34 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:19 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:19</guid> <description> <p> Thanks for resolving this ticket, Eric! </p> <p> P.S. The bug reported to Microsoft Connect has been resolved saying "this issue has been fixed. The fix should show up in a future release of Visual C++." </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Wed, 05 Oct 2011 01:47:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:20 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:20</guid> <description> <p> Very glad to hear it. And thanks for your contribution to Boost! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Sat, 15 Oct 2011 19:24:42 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:21 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:21</guid> <description> <p> There seems to be a problem with this on gcc-4.4.3. See, for instance, <a class="ext-link" href="http://beta.boost.org/development/tests/release/developer/output/Sandia-gcc-4-4-3_0x-boost-bin-v2-libs-spirit-test-karma_actions-p2-test-gcc-4-4-3_0x-debug-karma.html"><span class="icon">​</span>this</a>. Michel, can you please look into this soon? We're about to lock down the release branch for 1.48, and I hate to regress Boost.Foreach. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Sun, 16 Oct 2011 02:57:34 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:22 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:22</guid> <description> <p> I'm investigating now. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Sun, 16 Oct 2011 07:09:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:23 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:23</guid> <description> <p> The current implementation of C++11 BOOST_FOREACH is based on <strong><code>decltype</code></strong>. However, gcc-4.4 has a bug that prevents us from using <code>decltype</code> in <code>BOOST_FOREACH</code>. (The bug has been fixed in gcc-4.5 and newer versions.) </p> <p> The reason I used <code>decltype</code> rather than <code>auto</code> is that </p> <ul><li><code>auto &amp;&amp;</code> is buggy in gcc-4.4.*, 4.5.*, 4.6.0 and so we should not use it. (This bug is already fixed in gcc-4.6.1 and 4.7.) </li><li><code>decltype</code> is more widely available than <code>auto</code>. </li><li>binding rvalue ranges to <strong>const</strong> references can be easily implemented with <code>decltype</code> than with <code>auto</code>. </li></ul><p> Short-term fixed would be: </p> <ol class="upperalpha"><li>Revert to C++03 BOOST_FOREACH on gcc-4.4 </li><li>Disable <strong>const</strong> reference biding of rvalue ranges on gcc-4.4. That is, rvalue ranges are bound to <strong>const or non-const</strong> rvalue ranges using <code>auto &amp;&amp;</code>. In spite of the above bug, <code>auto &amp;&amp;</code> can be safely used in gcc-4.4, since lvalues are allowed to be bound to rvalue references in gcc-4.4. </li></ol><p> A and B are extremely easy to do without causing any error. </p> <p> Long-term fixed would be </p> <ol class="upperalpha" start="3"><li>Implement "<strong>const</strong> reference binding of rvalue ranges" with <code>auto &amp;&amp;</code> on gcc-4.4. I already implemented it in this <a class="ext-link" href="http://lists.boost.org/Archives/boost/2011/04/180591.php"><span class="icon">​</span>post</a>. </li></ol><p> Comments? I'm ready to make patches. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Sun, 16 Oct 2011 12:13:29 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">fix_gcc_4_4_regression_by_C.patch</span> </li> </ul> <p> A patch for fixing gcc-4.4 regression (against trunk). This patch implements C of comment 23. </p> Ticket Michel Morin <mimomorin@…> Sun, 16 Oct 2011 12:20:54 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:24 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:24</guid> <description> <p> Attached a patch that implements C of comment 23. This patch should only affect a C++0x mode of gcc-4.4. </p> <p> I ported the code in this <a class="ext-link" href="http://lists.boost.org/Archives/boost/2011/04/180591.php"><span class="icon">​</span>post</a>. But, due to <code>auto&amp;&amp;</code> bug in gcc-4.4, I needed to change the code for adding <code>const</code> qualification to rvalue ranges. With this patch, <code>BOOST_FOREACH(DECL, EXPR)</code> does the following in a C++0x mode of gcc-4.4: </p> <ol><li>Expand EXPR's lifetime <pre class="wiki">auto &amp;&amp; tmp = EXPR </pre></li><li>Add const if EXPR is rvalue <pre class="wiki">auto &amp;&amp; rng = add_const_if&lt; boost::is_rvalue_reference&lt;decltype( (EXPR) )&amp;&amp;&gt; &gt;(tmp) </pre></li><li>Do the usual range-based for loop over <code>rng</code> </li></ol><p> <code>libs/foreach/test/</code> ran successfully on gcc (4.3 - 4.6 and 4.7 (experimental)) and clang (3.1(trunk) and Apple version 2.1) both in C++03 and C++11 modes. I also tested <code>libs/spirit/test/karma/actions.cpp</code> on gcc-4.4 in a C++11 mode and it ran fine. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Sun, 16 Oct 2011 16:08:13 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:25 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:25</guid> <description> <p> Great! I've applied the patch to both trunk and (throwing caution to the wind) to release. Thanks once again for your help. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Sun, 16 Oct 2011 17:48:05 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:26 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:26</guid> <description> <p> Sorry, Eric. Could you revert the previous patch? I found a regression caused by the patch (which was not caught by the test). </p> <p> I've realized that gcc-4.4 is really a mess to implement "const reference binding of rvalue ranges". We shouldn't try to implement it unless we have reliable test. Bugs in gcc-4.4 are appeared when using BOOST_FOREACH in function templates. We should extend the existing test to cover those cases. </p> <p> So it seems that we have only two options for this release: A or B of comment 23. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Sun, 16 Oct 2011 18:53:51 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">revert_to_cxx_03.patch</span> </li> </ul> <p> Patch that implements A of comment 23 (against trunk before applying the previous patch). </p> Ticket Michel Morin <mimomorin@…> Sun, 16 Oct 2011 18:55:42 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:27 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:27</guid> <description> <p> Attached a patch that implements A (reverting to the C++03 BOOST_FOREACH on gcc-4.4). </p> <p> I've found that even with the simplest implementation of B </p> <pre class="wiki">... if (bool is_rng_defined) = false) {} else for (auto &amp;&amp;rng = (EXPR); !is_rng_defined; is_rng_defined = true) ... </pre><p> we can make a regression due to the nasty <code>auto</code> bug in gcc-4.4. So we have only one choice: A. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Sun, 16 Oct 2011 19:11:35 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:28 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:28</guid> <description> <p> OK, done. Thanks again. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Mon, 17 Oct 2011 15:17:33 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:29 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:29</guid> <description> <p> On gcc-4.3 (C++11), I found a regression that was not caught by the test. Due to auto type deduction bugs (<code>decltype</code>) in template functions, the following code does not compile on gcc-4.3 (C++11) with Boost trunk </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;boost/foreach.hpp&gt; template&lt;typename T&gt; typename boost::mpl::if_&lt;boost::is_rvalue_reference&lt;T&amp;&amp;&gt;, T const, T&gt;::type add_const_if_rvalue(T&amp;&amp; t) { return t; } template &lt;typename T&gt; void f() { BOOST_FOREACH(int const&amp; i, add_const_if_rvalue(std::vector&lt;int&gt;(3, 0))) { std::cout &lt;&lt; i &lt;&lt; std::endl; } } int main (int argc, char* argv[]) { f&lt;void&gt;(); return 0; } </pre><p> This code compiles fine on gcc-4.3 (C++11) with Boost.1.47. It also compiles fine on gcc-4.5, 4.6, 4.7 (C++11) with Boost trunk. </p> <p> Do we need to revert to the C++03 BOOST_FOREACH on gcc-4.3 too? Patch is pretty simple. </p> <div class="wiki-code"> <div class="diff"> <ul class="entries"> <li class="entry"> <h2> <a>boost/foreach.hpp</a> </h2> <table class="trac-diff inline" cellspacing="0"> <colgroup> <col class="lineno"/><col class="lineno"/><col class="content"/> </colgroup> <thead> <tr> <th title="File boost/foreach.hpp (revision 75012)"> </th> <th title="File boost/foreach.hpp (working copy)"> </th> <td> <em></em> &nbsp; </td> </tr> </thead> <tbody class="unmod"> <tr> <th>34</th><th>34</th><td class="l"><span>// With these C++0x features, temporary collections can be bound to </span></td> </tr> <tr> <th>35</th><th>35</th><td class="l"><span>// rvalue references and their lifetime is extended. No copy/move is needed.</span></td> </tr> <tr> <th>36</th><th>36</th><td class="l"><span>#if !defined(BOOST_NO_DECLTYPE) &amp;&amp; !defined(BOOST_NO_RVALUE_REFERENCES)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \</span></td> </tr> </tbody> <tbody class="mod"> <tr class="first"> <th>37</th><th>&nbsp;</th><td class="l"><span>&nbsp;&amp;&amp; !(BOOST_WORKAROUND(__GNUC__, == 4) &amp;&amp; (__GNUC_MINOR__ <del>=</del>= 4) &amp;&amp; !defined(BOOST_INTEL) &amp;&amp;&nbsp; &nbsp; &nbsp; \</span></td> </tr> <tr class="last"> <th>&nbsp;</th><th>37</th><td class="r"><span>&nbsp;&amp;&amp; !(BOOST_WORKAROUND(__GNUC__, == 4) &amp;&amp; (__GNUC_MINOR__ <ins>&lt;</ins>= 4) &amp;&amp; !defined(BOOST_INTEL) &amp;&amp;&nbsp; &nbsp; &nbsp; \</span></td> </tr> </tbody> <tbody class="unmod"> <tr> <th>38</th><th>38</th><td class="l"><span>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;!defined(BOOST_CLANG))</span></td> </tr> <tr> <th>39</th><th>39</th><td class="l"><span># define BOOST_FOREACH_USE_RVALUE_REFERENCE_BINDING</span></td> </tr> <tr> <th>40</th><th>40</th><td class="l"><span>// Some compilers let us detect even const-qualified rvalues at compile-time</span></td> </tr> </tbody> </table> </li> </ul> </div></div> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Tue, 18 Oct 2011 03:55:20 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:30 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:30</guid> <description> <p> Thanks for your thoroughness on this issue. It's much appreciated. I've made your suggested change on trunk and release. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 20 Oct 2011 16:34:58 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:31 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:31</guid> <description> <p> <strong>*Regressions for compilers supporting C++11 lambda</strong>* </p> <p> Because the current C++11 BOOST_FOREACH uses <code>decltype</code> rather than <code>auto</code>, it cannot be used with C++11 lambda. This is possibly a serious regression. The following code compiles fine on VC++10 and gcc 4.5-4.7 with Boost 1.47, but fails to compile with Boost trunk: </p> <pre class="wiki">#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;boost/foreach.hpp&gt; #define BOOST_RESULT_OF_USE_DECLTYPE #include &lt;boost/range/adaptor/transformed.hpp&gt; int main (int argc, char* argv[]) { std::vector&lt;int&gt; v(3, 0); BOOST_FOREACH(int x, v | boost::adaptors::transformed([](int i){ return i + 1; })) { std::cout &lt;&lt; x &lt;&lt; std::endl; } return 0; } </pre><p> I know the release branch is already closed, but how about deferring C++11 support to Boost 1.49? </p> <p> Sorry for repeatedly troubling you. I should have noticed this regression earlier and I shouldn't have used <code>decltype</code> to workaround gcc's <code>auto</code> bugs. </p> </description> <category>Ticket</category> </item> <item> <author>Michel Morin <mimomorin@…></author> <pubDate>Thu, 20 Oct 2011 23:37:41 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:32 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:32</guid> <description> <p> To support the C++11 BOOST_FOREACH, we need to address the following: </p> <ul><li><strong>Extending test cases</strong> </li></ul><blockquote> <p> Especially, use BOOST_FOREACH in function templates and use BOOST_FOREACH with C++11 lambda. </p> </blockquote> <ul><li><strong>Workaround gcc's <code>auto</code> declaration bugs in function templates</strong> </li></ul><blockquote> <p> Except gcc 4.7, gcc's <code>auto</code> declarations in function templates do not work correctly. Even with gcc 4.6.1, </p> <pre class="wiki"> auto&amp;&amp; rng = add_const_if_rvalue(std::vector&lt;int&gt;(3, 0)); </pre><p> fails to compile (in function templates). </p> </blockquote> <p> It is possible that compilers have other unkown bugs on <code>auto</code> declarations, and so it might be reasonable to have a way to avoid regressions: </p> <ul><li><strong>Adding configuration macro BOOST_FOREACH_USE_AUTO_DECLARATIONS</strong> </li></ul><blockquote> <p> The C++11 BOOST_FOREACH gets enabled on compilers with rvalue references and <code>auto</code> support, only if BOOST_FOREACH_USE_AUTO_DECLARATIONS is defined by users. </p> </blockquote> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Fri, 21 Oct 2011 03:52:19 GMT</pubDate> <title>status changed; resolution deleted https://svn.boost.org/trac10/ticket/5475#comment:33 https://svn.boost.org/trac10/ticket/5475#comment:33 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">fixed</span> </li> </ul> <p> This change has made me nervous, so I have completely reverted all changes for the 1.48 release. We'll give it another go in 1.49. </p> Ticket Michel Morin <mimomorin@…> Tue, 08 Nov 2011 20:05:16 GMT attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">foreach_use_cxx11.patch</span> </li> </ul> <p> A patch (against trunk) that implements C++11 BOOST_FOREACH and workarounds for auto declaration bugs in gcc 4.4-4.6. </p> Ticket Michel Morin <mimomorin@…> Tue, 08 Nov 2011 20:09:03 GMT attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">foreach_add_new_tests.patch</span> </li> </ul> <p> A patch (against trunk) that adds tests for gcc bugs and C++11 lambdas. This patch also adds tests for noncopyable rvalue collections. </p> Ticket Michel Morin <mimomorin@…> Tue, 08 Nov 2011 20:47:07 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:34 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:34</guid> <description> <p> Finally, I came up with workarounds for gcc's auto type deduction bugs. Now BOOST_FOREACH consists of three implementations: C++03 BOOST_FOREACH, C++11 BOOST_FOREACH and workarounds for gcc bugs. All the existing tests and new tests (involving function templates and C++11 lambdas) ran successfully on gcc and clang. </p> <p> To workaround gcc bugs, I used a hybrid of C++11 and C++03 codes: </p> <ol><li>Bind a const reference to a range using <code>auto const&amp;</code>. If the range is non-const lvalue, constness of the reference is stripped off via <code>const_cast</code> when accessing the reference. </li><li><code>begin</code> and <code>end</code> iterators are stored as <code>auto_any_t</code> to avoid the bugs. </li></ol><p> This workaround code is enabled in C++11 modes of gcc 4.4-4.6. </p> <p> On MSVC++ 10, I changed to use the C++03 BOOST_FOREACH code. Since this compiler doesn't support iteration over noncopyable rvalue ranges, it's not worth taking a risk for regressions. </p> <p> I also added a few tests: </p> <ul><li>noncopyable_rvalue_*.cpp: This test emits expected-failures if <code>BOOST_FOREACH_USE_CXX11</code> or <code>BOOST_FOREACH_USE_CXX11_GCC_WORKAROUND</code> is not defined. </li><li>cxx11_gcc_workaround_*.cpp: This test needs support of rvalue references. On compilers without rvalue reference support, this test succeeds unconditionally. </li><li>cxx11_lambda_*.cpp: This test needs support of C++11 lambdas. On compilers without C++11 lambdas support, this test succeeds unconditionally. </li><li>char_array_fail_*.cpp: A test case that should fail to compile (<code>compile-fail</code> is specified in Jamfile). This test tries to iterating over a char array. </li><li>rvalue_nonconst_access_fail_*.cpp: A test case that should fail to compile (<code>compile-fail</code> is specified in Jamfile). This test tries to capture elements in an rvalue range by non-const references. </li></ul><p> Patches for <code>boost/foreach.hpp</code> and <code>libs/foreach/test/</code> are attached. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Michel Morin</dc:creator> <pubDate>Sun, 03 Jun 2012 08:01:33 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/5475 https://svn.boost.org/trac10/ticket/5475 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">foreach_use_cxx11_v2.patch</span> </li> </ul> <p> Updated patch of foreach_use_cxx11.patch. With this patch, we can iterate over noncopyable temporary ranges on VC++ 11 as well. </p> Ticket Michel Morin Sun, 03 Jun 2012 08:04:27 GMT <link>https://svn.boost.org/trac10/ticket/5475#comment:35 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:35</guid> <description> <p> I confirmed that VC++ 11 (beta) fixed the bug in reference binding of noncopyable temporaries. So we can iterate over noncopyable rvalue ranges on VC++ 11. I ran the tests on VC++11 with my previous patch, but some tests failed because of VC++'s bug in two-phase name look-up. </p> <p> So, again, I updated the patch. Now, all the tests (incl. tests for noncopyable/nonmovable rvalue ranges and C++11 lambdas) passed on VC++ 11, gcc 4.4-4.7, clang 2.9-3.1. </p> <p> Updated patch attached in this ticket: <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/5475/foreach_use_cxx11_v2.patch"><span class="icon">​</span>https://svn.boost.org/trac/boost/attachment/ticket/5475/foreach_use_cxx11_v2.patch</a> </p> <p> Also, patch for the tests attached in this ticket: <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/5475/foreach_add_new_tests.patch"><span class="icon">​</span>https://svn.boost.org/trac/boost/attachment/ticket/5475/foreach_add_new_tests.patch</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Michel Morin</dc:creator> <pubDate>Thu, 16 Aug 2012 06:57:29 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:36 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:36</guid> <description> <p> Before gcc 4.7.1 and gcc 4.8.0 (not yet released), auto type deduction in function templates is done differently than the one in non-template functions. This resulted in many bugs in gcc 4.4-4.6 for auto type deduction in function templates. So my patch does workarounds for those compilers. </p> <p> In gcc 4.7.0, I don't know of any bugs that affect (normal) C++11 implementation of BOOST_FOREACH. But gcc 4.7.0 still contains bugs of auto type deduction in function templates (c.f. <a class="ext-link" href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53484"><span class="icon">​</span>PR53484 ("Wrong auto in lambdas in function templates")</a>), and there might be a bug that needs workarounds as in gcc 4.4-4.6. </p> <p> Would it be better to do workarounds for gcc 4.7.0, too? (My patch does not apply workarounds for gcc 4.7.0.) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Thu, 16 Aug 2012 08:04:48 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:37 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:37</guid> <description> <p> I'll be honest with you, Michel. At this point, given the sheer size and complexity of your patch, and the number of broken compilers that half-implement C++11 that I need to support, and the past difficulties we experienced trying to get this fix to fly, it's looking highly doubtful that I'll be taking this patch. Especially considering that C++11 users have a better option: use C++11's range-based for. I can tell you've invested a lot of effort into this, and I greatly appreciate it. </p> <p> I would very much like to move <code>BOOST_FOREACH</code> into maintenance mode. It's a relic. I don't expect I'll be adding any new features to it. </p> <p> I'll leave the bog open for now and may reconsider. But for now, I wouldn't spend any more time on this if I were you. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Michel Morin</dc:creator> <pubDate>Thu, 16 Aug 2012 08:30:37 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/5475#comment:38 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/5475#comment:38</guid> <description> <blockquote class="citation"> <p> I would very much like to move <code>BOOST_FOREACH</code> into maintenance mode. It's a relic. I don't expect I'll be adding any new features to it. </p> </blockquote> <p> I think it's reasonable that <code>BOOST_FOREACH</code> becomes in a maintenance mode. <br /><br /> </p> <blockquote class="citation"> <p> I'll leave the bog open for now and may reconsider. But for now, I wouldn't spend any more time on this if I were you. </p> </blockquote> <p> OK. I'll dive into the C++11 world as you do rather than struggle with half-broken C++11 compilers. That would be more fun ;) </p> <p> Thanks for your reply, Eric! </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Eric Niebler</dc:creator> <pubDate>Fri, 16 Nov 2012 00:03:15 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/5475#comment:39 https://svn.boost.org/trac10/ticket/5475#comment:39 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> Closing this out. I won't be adding any more features to <code>BOOST_FOREACH</code>. Thanks for your efforts, Michel. </p> Ticket