| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
| <html><head> |
| <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"> |
| |
| |
| <title>C++ Standard Library Defect Report List</title> |
| <style type="text/css"> |
| p {text-align:justify} |
| li {text-align:justify} |
| ins {background-color:#A0FFA0} |
| del {background-color:#FFA0A0} |
| </style> |
| </head><body> |
| <table> |
| <tbody><tr> |
| <td align="left">Doc. no.</td> |
| <td align="left">N2728=08-0238</td> |
| </tr> |
| <tr> |
| <td align="left">Date:</td> |
| <td align="left">2008-08-24</td> |
| </tr> |
| <tr> |
| <td align="left">Project:</td> |
| <td align="left">Programming Language C++</td> |
| </tr> |
| <tr> |
| <td align="left">Reply to:</td> |
| <td align="left">Howard Hinnant <<a href="mailto:howard.hinnant@gmail.com">howard.hinnant@gmail.com</a>></td> |
| </tr> |
| </tbody></table> |
| <h1>C++ Standard Library Defect Report List (Revision R59)</h1> |
| |
| <p>Reference ISO/IEC IS 14882:1998(E)</p> |
| <p>Also see:</p> |
| <ul> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-toc.html">Table of Contents</a> for all library issues.</li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html">Index by Section</a> for all library issues.</li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html">Index by Status</a> for all library issues.</li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html">Library Active Issues List</a></li> |
| <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a></li> |
| </ul> |
| <p>This document contains only library issues which have been closed |
| by the Library Working Group (LWG) after being found to be defects |
| in the standard. That is, issues which have a status of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a>, or <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#RR">RR</a>. See the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html">Library Closed Issues List</a> for issues closed as non-defects. See the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html">Library Active Issues List</a> for active issues and more information. The |
| introductory material in that document also applies to this |
| document.</p> |
| |
| <h2>Revision History</h2> |
| <ul> |
| <li>R59: |
| 2008-08-22 pre-San Francisco mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>192 open issues, up by 9.</li> |
| <li>686 closed issues, up by 0.</li> |
| <li>878 issues total, up by 9.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#870">870</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#871">871</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#872">872</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#873">873</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#874">874</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#875">875</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#876">876</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#877">877</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#878">878</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R58: |
| 2008-07-28 mid-term mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>183 open issues, up by 12.</li> |
| <li>686 closed issues, down by 4.</li> |
| <li>869 issues total, up by 8.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#862">862</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#863">863</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#864">864</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#865">865</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#866">866</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#867">867</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#868">868</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#869">869</a>.</li> |
| <li>Changed the following issues from Pending NAD Editorial to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#393">393</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#557">557</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#592">592</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#754">754</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#757">757</a>.</li> |
| <li>Changed the following issues from Pending WP to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#644">644</a>.</li> |
| <li>Changed the following issues from WP to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#387">387</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#629">629</a>.</li> |
| <li>Changed the following issues from Pending NAD Editorial to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#709">709</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R57: |
| 2008-06-27 post-Sophia Antipolis mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>171 open issues, down by 20.</li> |
| <li>690 closed issues, up by 43.</li> |
| <li>861 issues total, up by 23.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following NAD issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#840">840</a>.</li> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#841">841</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#843">843</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#845">845</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#846">846</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#847">847</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#849">849</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#853">853</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#854">854</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#855">855</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#856">856</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#857">857</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#858">858</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#859">859</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#860">860</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#861">861</a>.</li> |
| <li>Added the following Open issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#839">839</a>.</li> |
| <li>Added the following Ready issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#842">842</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#844">844</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#848">848</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#850">850</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#852">852</a>.</li> |
| <li>Added the following Review issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#851">851</a>.</li> |
| <li>Changed the following issues from New to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#826">826</a>.</li> |
| <li>Changed the following issues from Open to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#570">570</a>.</li> |
| <li>Changed the following issues from New to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#786">786</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#831">831</a>.</li> |
| <li>Changed the following issues from Open to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#756">756</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#767">767</a>.</li> |
| <li>Changed the following issues from New to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#723">723</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#726">726</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#794">794</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#815">815</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#825">825</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#830">830</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#833">833</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>.</li> |
| <li>Changed the following issues from Ready to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#471">471</a>.</li> |
| <li>Changed the following issues from Review to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#539">539</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#711">711</a>.</li> |
| <li>Changed the following issues from New to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#713">713</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#714">714</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#769">769</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#772">772</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#779">779</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#787">787</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#805">805</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#806">806</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#807">807</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#808">808</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#809">809</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#813">813</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#824">824</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#829">829</a>.</li> |
| <li>Changed the following issues from Open to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#180">180</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#396">396</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#720">720</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#762">762</a>.</li> |
| <li>Changed the following issues from Review to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#691">691</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#728">728</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#771">771</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#776">776</a>.</li> |
| <li>Changed the following issues from New to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#692">692</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#698">698</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#752">752</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#804">804</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#823">823</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#828">828</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#832">832</a>.</li> |
| <li>Changed the following issues from Open to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#23">23</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#675">675</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#734">734</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#803">803</a>.</li> |
| <li>Changed the following issues from Ready to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#758">758</a>.</li> |
| <li>Changed the following issues from Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#387">387</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518">518</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550">550</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#574">574</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#595">595</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#596">596</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#612">612</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#618">618</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#629">629</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#638">638</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#672">672</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#673">673</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#685">685</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#710">710</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#715">715</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#722">722</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#740">740</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#743">743</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#744">744</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#746">746</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#749">749</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#755">755</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#759">759</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#761">761</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#766">766</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#768">768</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#770">770</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#775">775</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#777">777</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#778">778</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#781">781</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#782">782</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#783">783</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#789">789</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#792">792</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#798">798</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R56: |
| 2008-05-16 pre-Sophia Antipolis mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>191 open issues, up by 24.</li> |
| <li>647 closed issues, up by 1.</li> |
| <li>838 issues total, up by 25.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#814">814</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#815">815</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#816">816</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#817">817</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#818">818</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#819">819</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#820">820</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#821">821</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#822">822</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#823">823</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#824">824</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#825">825</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#826">826</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#827">827</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#828">828</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#829">829</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#830">830</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#831">831</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#832">832</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#833">833</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#834">834</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#835">835</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#836">836</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#837">837</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#838">838</a>.</li> |
| <li>Changed the following issues from New to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#802">802</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R55: |
| 2008-03-14 post-Bellevue mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>167 open issues, down by 39.</li> |
| <li>646 closed issues, up by 65.</li> |
| <li>813 issues total, up by 26.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following Dup issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#795">795</a>.</li> |
| <li>Added the following NAD issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#790">790</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#791">791</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#796">796</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#797">797</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#799">799</a>.</li> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#788">788</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#794">794</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#802">802</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#804">804</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#805">805</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#806">806</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#807">807</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#808">808</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#809">809</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#810">810</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#811">811</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#812">812</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#813">813</a>.</li> |
| <li>Added the following Open issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#793">793</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#800">800</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#801">801</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#803">803</a>.</li> |
| <li>Added the following Ready issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#789">789</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#792">792</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#798">798</a>.</li> |
| <li>Changed the following issues from NAD Future to Dup: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#116">116</a>.</li> |
| <li>Changed the following issues from NAD Future to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#188">188</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>.</li> |
| <li>Changed the following issues from New to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#729">729</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#730">730</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#731">731</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#733">733</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#735">735</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#736">736</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#737">737</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#739">739</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#741">741</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#745">745</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#748">748</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#763">763</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#764">764</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#773">773</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#784">784</a>.</li> |
| <li>Changed the following issues from Open to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#388">388</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#462">462</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#579">579</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#627">627</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#653">653</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#686">686</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#707">707</a>.</li> |
| <li>Changed the following issues from NAD Future to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#390">390</a>.</li> |
| <li>Changed the following issues from Open to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#529">529</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#626">626</a>.</li> |
| <li>Changed the following issues from Review to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#645">645</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#684">684</a>.</li> |
| <li>Changed the following issues from NAD Future to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#128">128</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#180">180</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#190">190</a>.</li> |
| <li>Changed the following issues from New to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#617">617</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#718">718</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#719">719</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#720">720</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#724">724</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#732">732</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#734">734</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#742">742</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#747">747</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#750">750</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#753">753</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#756">756</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#760">760</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#762">762</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#767">767</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#774">774</a>.</li> |
| <li>Changed the following issues from Ready to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#675">675</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#676">676</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#688">688</a>.</li> |
| <li>Changed the following issues from New to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#709">709</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#717">717</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#725">725</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#738">738</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#754">754</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#757">757</a>.</li> |
| <li>Changed the following issues from Open to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#424">424</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#557">557</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#625">625</a>.</li> |
| <li>Changed the following issues from New to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#710">710</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#715">715</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#722">722</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#740">740</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#743">743</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#744">744</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#746">746</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#749">749</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#755">755</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#758">758</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#759">759</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#761">761</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#766">766</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#768">768</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#770">770</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#775">775</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#777">777</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#778">778</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#781">781</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#782">782</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#783">783</a>.</li> |
| <li>Changed the following issues from Open to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#387">387</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#471">471</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550">550</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#612">612</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#629">629</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#673">673</a>.</li> |
| <li>Changed the following issues from Review to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518">518</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#574">574</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#596">596</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#618">618</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#638">638</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#672">672</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#685">685</a>.</li> |
| <li>Changed the following issues from New to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#711">711</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#728">728</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#771">771</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#776">776</a>.</li> |
| <li>Changed the following issues from Open to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#539">539</a>.</li> |
| <li>Changed the following issues from Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#561">561</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#562">562</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#563">563</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#567">567</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#581">581</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#620">620</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#621">621</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#622">622</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#623">623</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#624">624</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#661">661</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#664">664</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#665">665</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#666">666</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#674">674</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#679">679</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#680">680</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#687">687</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#689">689</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#693">693</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#694">694</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#695">695</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#700">700</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#703">703</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#705">705</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#706">706</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#527">527</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R54: |
| 2008-02-01 pre-Bellevue mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>206 open issues, up by 23.</li> |
| <li>581 closed issues, up by 0.</li> |
| <li>787 issues total, up by 23.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#765">765</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#766">766</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#767">767</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#768">768</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#769">769</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#770">770</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#771">771</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#772">772</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#773">773</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#774">774</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#775">775</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#776">776</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#777">777</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#778">778</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#779">779</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#780">780</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#781">781</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#782">782</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#783">783</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#784">784</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#785">785</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#786">786</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#787">787</a>.</li> |
| <li>Changed the following issues from NAD Future to Dup: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#105">105</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#348">348</a>.</li> |
| <li>Changed the following issues from NAD Future to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#353">353</a>.</li> |
| <li>Changed the following issues from New to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#697">697</a>.</li> |
| <li>Changed the following issues from NAD Future to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#388">388</a>.</li> |
| <li>Changed the following issues from Open to Tentatively Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#527">527</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R53: |
| 2007-12-09 mid-term mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>183 open issues, up by 11.</li> |
| <li>581 closed issues, down by 1.</li> |
| <li>764 issues total, up by 10.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#755">755</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#756">756</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#757">757</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#758">758</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#759">759</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#760">760</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#761">761</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#762">762</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#763">763</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#764">764</a>.</li> |
| <li>Changed the following issues from NAD to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463">463</a>.</li> |
| <li>Changed the following issues from Pending WP to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#607">607</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#608">608</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#654">654</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#655">655</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#677">677</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#682">682</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R52: |
| 2007-10-19 post-Kona mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>172 open issues, up by 4.</li> |
| <li>582 closed issues, up by 27.</li> |
| <li>754 issues total, up by 31.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#724">724</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#725">725</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#726">726</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#727">727</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#728">728</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#729">729</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#730">730</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#731">731</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#732">732</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#733">733</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#734">734</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#735">735</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#736">736</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#737">737</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#738">738</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#739">739</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#740">740</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#741">741</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#742">742</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#743">743</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#744">744</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#745">745</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#746">746</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#747">747</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#748">748</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#749">749</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#750">750</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#751">751</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#752">752</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#753">753</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#754">754</a>.</li> |
| <li>Changed the following issues from NAD Future to Dup: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#77">77</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a>.</li> |
| <li>Changed the following issues from New to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#639">639</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#657">657</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#663">663</a>.</li> |
| <li>Changed the following issues from Open to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#548">548</a>.</li> |
| <li>Changed the following issues from New to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#546">546</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#550">550</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#564">564</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#565">565</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#573">573</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#585">585</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#588">588</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#627">627</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#629">629</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#630">630</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#632">632</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#635">635</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#653">653</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#659">659</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#667">667</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#668">668</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#669">669</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#670">670</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#671">671</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#673">673</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#686">686</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#704">704</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#707">707</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#708">708</a>.</li> |
| <li>Changed the following issues from New to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#393">393</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#592">592</a>.</li> |
| <li>Changed the following issues from New to Pending WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#607">607</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#608">608</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#654">654</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#655">655</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#677">677</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#682">682</a>.</li> |
| <li>Changed the following issues from New to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#561">561</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#562">562</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#563">563</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#567">567</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#581">581</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#595">595</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#620">620</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#621">621</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#622">622</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#623">623</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#624">624</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#661">661</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#664">664</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#665">665</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#666">666</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#674">674</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#675">675</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#676">676</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#679">679</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#687">687</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#688">688</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#689">689</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#693">693</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#694">694</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#695">695</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#700">700</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#703">703</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#705">705</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#706">706</a>.</li> |
| <li>Changed the following issues from Open to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#680">680</a>.</li> |
| <li>Changed the following issues from New to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#574">574</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#596">596</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#618">618</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#638">638</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#645">645</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#672">672</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#684">684</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#685">685</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#691">691</a>.</li> |
| <li>Changed the following issues from New to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#552">552</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#634">634</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#650">650</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#651">651</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#652">652</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#678">678</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#681">681</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#699">699</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#712">712</a>.</li> |
| <li>Changed the following issues from Open to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#258">258</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#401">401</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#524">524</a>.</li> |
| <li>Changed the following issues from Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#488">488</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#577">577</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#660">660</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R51: |
| 2007-09-09 pre-Kona mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>168 open issues, up by 15.</li> |
| <li>555 closed issues, up by 0.</li> |
| <li>723 issues total, up by 15.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#709">709</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#710">710</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#711">711</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#712">712</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#713">713</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#714">714</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#715">715</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#716">716</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#717">717</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#718">718</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#719">719</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#720">720</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#721">721</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#722">722</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#723">723</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R50: |
| 2007-08-05 post-Toronto mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>153 open issues, down by 5.</li> |
| <li>555 closed issues, up by 17.</li> |
| <li>708 issues total, up by 12.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#697">697</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#698">698</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#699">699</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#700">700</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#701">701</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#702">702</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#703">703</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#704">704</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#705">705</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#706">706</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#707">707</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#708">708</a>.</li> |
| <li>Changed the following issues from New to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#583">583</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#584">584</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#662">662</a>.</li> |
| <li>Changed the following issues from Open to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#528">528</a>.</li> |
| <li>Changed the following issues from New to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#637">637</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#647">647</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#658">658</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#690">690</a>.</li> |
| <li>Changed the following issues from Open to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#525">525</a>.</li> |
| <li>Changed the following issues from Pending NAD Editorial to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#553">553</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#571">571</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#591">591</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#633">633</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#636">636</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#641">641</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#642">642</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#648">648</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#649">649</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#656">656</a>.</li> |
| <li>Changed the following issues from New to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#579">579</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#631">631</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#680">680</a>.</li> |
| <li>Changed the following issues from Pending WP to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#258">258</a>.</li> |
| <li>Changed the following issues from Ready to Pending WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#644">644</a>.</li> |
| <li>Changed the following issues from New to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#577">577</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#660">660</a>.</li> |
| <li>Changed the following issues from Open to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#488">488</a>.</li> |
| <li>Changed the following issues from Open to Review: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518">518</a>.</li> |
| <li>Changed the following issues from Ready to TRDec: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#604">604</a>.</li> |
| <li>Changed the following issues from DR to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#453">453</a>.</li> |
| <li>Changed the following issues from Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#551">551</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#566">566</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#628">628</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#640">640</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#643">643</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#646">646</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R49: |
| 2007-06-23 pre-Toronto mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>158 open issues, up by 13.</li> |
| <li>538 closed issues, up by 7.</li> |
| <li>696 issues total, up by 20.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#677">677</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#678">678</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#679">679</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#680">680</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#681">681</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#682">682</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#684">684</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#685">685</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#686">686</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#687">687</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#688">688</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#689">689</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#690">690</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#691">691</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#692">692</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#693">693</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#694">694</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#695">695</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#696">696</a>.</li> |
| <li>Added the following Pending NAD Editorial issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#683">683</a>.</li> |
| <li>Changed the following issues from New to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#587">587</a>.</li> |
| <li>Changed the following issues from Open to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#590">590</a>.</li> |
| <li>Changed the following issues from New to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#636">636</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#642">642</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#648">648</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#649">649</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R48: |
| 2007-05-06 post-Oxford mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>145 open issues, down by 33.</li> |
| <li>531 closed issues, up by 53.</li> |
| <li>676 issues total, up by 20.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#657">657</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#658">658</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#659">659</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#660">660</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#661">661</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#662">662</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#663">663</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#664">664</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#665">665</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#666">666</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#667">667</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#668">668</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#669">669</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#670">670</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#671">671</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#672">672</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#673">673</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#674">674</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#675">675</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#676">676</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to Dup: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#479">479</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#536">536</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to NAD: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#385">385</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463">463</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#466">466</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#470">470</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#515">515</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526">526</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#547">547</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#560">560</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#572">572</a>.</li> |
| <li>Changed the following issues from NAD to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#351">351</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#357">357</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#368">368</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#499">499</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#514">514</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#516">516</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#544">544</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#555">555</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#558">558</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#482">482</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#615">615</a>.</li> |
| <li>Changed the following issues from NAD_Future to NAD Future: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#77">77</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#105">105</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#111">111</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#116">116</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#128">128</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#138">138</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#149">149</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#180">180</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#188">188</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#190">190</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#219">219</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#348">348</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#353">353</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#388">388</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#390">390</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#471">471</a>.</li> |
| <li>Changed the following issues from New to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#633">633</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#641">641</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#656">656</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to Pending NAD Editorial: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#532">532</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#553">553</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#571">571</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#591">591</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#594">594</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to Pending WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#258">258</a>.</li> |
| <li>Changed the following issues from New to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#566">566</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#628">628</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#640">640</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#643">643</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#644">644</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#646">646</a>.</li> |
| <li>Changed the following issues from Review to Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#551">551</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#604">604</a>.</li> |
| <li>Changed the following issues from Ready to TRDec: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#598">598</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#599">599</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#600">600</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#601">601</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#602">602</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#603">603</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#605">605</a>.</li> |
| <li>Changed the following issues from Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#543">543</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#545">545</a>.</li> |
| <li>Changed the following issues from Tentatively Ready to WP: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#201">201</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#206">206</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">233</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#254">254</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#416">416</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#422">422</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456">456</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#534">534</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#542">542</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#559">559</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#575">575</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#576">576</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#578">578</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#586">586</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#589">589</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#593">593</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#609">609</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#610">610</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#611">611</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#613">613</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#616">616</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#619">619</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R47: |
| 2007-03-09 pre-Oxford mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>178 open issues, up by 37.</li> |
| <li>478 closed issues, up by 0.</li> |
| <li>656 issues total, up by 37.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added the following New issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#620">620</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#621">621</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#622">622</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#623">623</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#624">624</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#627">627</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#628">628</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#629">629</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#630">630</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#631">631</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#632">632</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#633">633</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#634">634</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#635">635</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#636">636</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#637">637</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#638">638</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#639">639</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#640">640</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#641">641</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#642">642</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#643">643</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#644">644</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#645">645</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#646">646</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#647">647</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#648">648</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#649">649</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#650">650</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#651">651</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#652">652</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#653">653</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#654">654</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#655">655</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#656">656</a>.</li> |
| <li>Added the following Open issues: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#625">625</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#626">626</a>.</li> |
| <li>Changed the following issues from New to Open: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#570">570</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#580">580</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#582">582</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#590">590</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#612">612</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#614">614</a>.</li> |
| <li>Changed the following issues from New to Tentatively Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#547">547</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#553">553</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#560">560</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#571">571</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#572">572</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#575">575</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#576">576</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#578">578</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#586">586</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#589">589</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#591">591</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#593">593</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#594">594</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#609">609</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#610">610</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#611">611</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#613">613</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#615">615</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#616">616</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#619">619</a>.</li> |
| <li>Changed the following issues from Open to Tentatively Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#201">201</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#206">206</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">233</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#254">254</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#258">258</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#385">385</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#416">416</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#422">422</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456">456</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463">463</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#466">466</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#470">470</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#471">471</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#479">479</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#482">482</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#515">515</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526">526</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#532">532</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#536">536</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#542">542</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#559">559</a>.</li> |
| <li>Changed the following issues from Review to Tentatively Ready: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#534">534</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R46: |
| 2007-01-12 mid-term mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>141 open issues, up by 11.</li> |
| <li>478 closed issues, down by 1.</li> |
| <li>619 issues total, up by 10.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#610">610</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#619">619</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R45: |
| 2006-11-03 post-Portland mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>130 open issues, up by 0.</li> |
| <li>479 closed issues, up by 17.</li> |
| <li>609 issues total, up by 17.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#520">520</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#521">521</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530">530</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#537">537</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#538">538</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#540">540</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#541">541</a> to WP.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#516">516</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#544">544</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#554">554</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#555">555</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#558">558</a> to NAD.</li> |
| <li>Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#569">569</a> to Dup.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518">518</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#523">523</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#524">524</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#542">542</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#556">556</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#557">557</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#559">559</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#597">597</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#606">606</a> to Open.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#543">543</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#545">545</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#598">598</a> - <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#603">603</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#605">605</a> to Ready.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#551">551</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#604">604</a> to Review.</li> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#593">593</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#609">609</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R44: |
| 2006-09-08 pre-Portland mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>130 open issues, up by 6.</li> |
| <li>462 closed issues, down by 1.</li> |
| <li>592 issues total, up by 5.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#583">583</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#592">592</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R43: |
| 2006-06-23 mid-term mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>124 open issues, up by 14.</li> |
| <li>463 closed issues, down by 1.</li> |
| <li>587 issues total, up by 13.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#575">575</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#582">582</a>.</li> |
| <li>Reopened <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#255">255</a>.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#520">520</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#541">541</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#544">544</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#569">569</a> to Tentatively Ready.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R42: |
| 2006-04-21 post-Berlin mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>110 open issues, down by 16.</li> |
| <li>464 closed issues, up by 24.</li> |
| <li>574 issues total, up by 8.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#567">567</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#572">572</a>.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#499">499</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#501">501</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#506">506</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#509">509</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#511">511</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#514">514</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#517">517</a> to NAD.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#502">502</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#503">503</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#515">515</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#516">516</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#525">525</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#529">529</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#532">532</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#536">536</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#539">539</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#548">548</a> to Open.</li> |
| <li>Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#521">521</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#530">530</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#531">531</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#537">537</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#538">538</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#540">540</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#549">549</a> to Ready.</li> |
| <li>Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#247">247</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294">294</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#362">362</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#369">369</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#371">371</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#376">376</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#384">384</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#475">475</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#478">478</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#495">495</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#497">497</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#505">505</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#507">507</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#508">508</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#519">519</a> to WP.</li> |
| <li>Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#534">534</a> to Review.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R41: |
| 2006-02-24 pre-Berlin mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>126 open issues, up by 31.</li> |
| <li>440 closed issues, up by 0.</li> |
| <li>566 issues total, up by 31.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#536">536</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#566">566</a>.</li> |
| <li>Moved <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#342">342</a> from Ready to Open.</li> |
| <li>Reopened <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#309">309</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R40: |
| 2005-12-16 mid-term mailing. |
| <ul> |
| <li><b>Summary:</b><ul> |
| <li>95 open issues.</li> |
| <li>440 closed issues.</li> |
| <li>535 issues total.</li> |
| </ul></li> |
| <li><b>Details:</b><ul> |
| <li>Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#529">529</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#535">535</a>.</li> |
| </ul></li> |
| </ul> |
| </li> |
| <li>R39: |
| 2005-10-14 post-Mont Tremblant mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#526">526</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#528">528</a>. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280">280</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#461">461</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#464">464</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#465">465</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#467">467</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#468">468</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#474">474</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#496">496</a> from Ready to WP as per the vote from Mont Tremblant. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#247">247</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#294">294</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#342">342</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#362">362</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#369">369</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#371">371</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#376">376</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#384">384</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#475">475</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#478">478</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#495">495</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#497">497</a> from Review to Ready. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#498">498</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#506">506</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#509">509</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#510">510</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#511">511</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#512">512</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#513">513</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#514">514</a> from New to Open. |
| Moved issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#505">505</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#507">507</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#508">508</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#519">519</a> from New to Ready. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#500">500</a> from New to NAD. |
| Moved issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#518">518</a> from New to Review. |
| </li> |
| <li>R38: |
| 2005-07-03 pre-Mont Tremblant mailing. |
| Merged open TR1 issues in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#504">504</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#522">522</a>. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#523">523</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#523">523</a> |
| </li> |
| <li>R37: |
| 2005-06 mid-term mailing. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#498">498</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#503">503</a>. |
| </li> |
| <li>R36: |
| 2005-04 post-Lillehammer mailing. All issues in "ready" status except |
| for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#454">454</a> were moved to "DR" status, and all issues |
| previously in "DR" status were moved to "WP". |
| </li> |
| <li>R35: |
| 2005-03 pre-Lillehammer mailing. |
| </li> |
| <li>R34: |
| 2005-01 mid-term mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#488">488</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#494">494</a>. |
| </li> |
| <li>R33: |
| 2004-11 post-Redmond mailing. Reflects actions taken in Redmond. |
| </li> |
| <li>R32: |
| 2004-09 pre-Redmond mailing: reflects new proposed resolutions and |
| new issues received after the 2004-07 mailing. Added |
| new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#479">479</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#481">481</a>. |
| </li> |
| <li>R31: |
| 2004-07 mid-term mailing: reflects new proposed resolutions and |
| new issues received after the post-Sydney mailing. Added |
| new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#463">463</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#478">478</a>. |
| </li> |
| <li>R30: |
| Post-Sydney mailing: reflects decisions made at the Sydney meeting. |
| Voted all "Ready" issues from R29 into the working paper. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#460">460</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#462">462</a>. |
| </li> |
| <li>R29: |
| Pre-Sydney mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#441">441</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#457">457</a>. |
| </li> |
| <li>R28: |
| Post-Kona mailing: reflects decisions made at the Kona meeting. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#432">432</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#440">440</a>. |
| </li> |
| <li>R27: |
| Pre-Kona mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#404">404</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#431">431</a>. |
| </li> |
| <li>R26: |
| Post-Oxford mailing: reflects decisions made at the Oxford meeting. |
| All issues in Ready status were voted into DR status. All issues in |
| DR status were voted into WP status. |
| </li> |
| <li>R25: |
| Pre-Oxford mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#390">390</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#402">402</a>. |
| </li> |
| <li>R24: |
| Post-Santa Cruz mailing: reflects decisions made at the Santa Cruz |
| meeting. All Ready issues from R23 with the exception of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, which has been given a new proposed resolution, were |
| moved to DR status. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#383">383</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#389">389</a>. (Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#387">387</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#389">389</a> were discussed |
| at the meeting.) Made progress on issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a> have been moved to Ready status, and the only remaining |
| concerns with <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a> involve wording. |
| </li> |
| <li>R23: |
| Pre-Santa Cruz mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#367">367</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#382">382</a>. |
| Moved issues in the TC to TC status. |
| </li> |
| <li>R22: |
| Post-Curaçao mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#362">362</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#366">366</a>. |
| </li> |
| <li>R21: |
| Pre-Curaçao mailing. Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#351">351</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#361">361</a>. |
| </li> |
| <li>R20: |
| Post-Redmond mailing; reflects actions taken in Redmond. Added |
| new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#336">336</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a>, of which issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#347">347</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a> were added since Redmond, hence |
| not discussed at the meeting. |
| |
| All Ready issues were moved to DR status, with the exception of issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#284">284</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241">241</a>, and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a>. |
| |
| Noteworthy issues discussed at Redmond include |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#120">120</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#202">202</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">233</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#270">270</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#254">254</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>. |
| </li> |
| <li>R19: |
| Pre-Redmond mailing. Added new issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#335">335</a>. |
| </li> |
| <li>R18: |
| Post-Copenhagen mailing; reflects actions taken in Copenhagen. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#312">312</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#317">317</a>, and discussed |
| new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#271">271</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#314">314</a>. |
| |
| Changed status of issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#118">118</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#136">136</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#153">153</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#165">165</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#171">171</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#183">183</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#184">184</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#185">185</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#186">186</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#214">214</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#221">221</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#234">234</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#237">237</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#243">243</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#248">248</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#251">251</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#252">252</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#256">256</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#260">260</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#261">261</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#262">262</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#263">263</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#265">265</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#268">268</a> |
| to DR. |
| |
| Changed status of issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#49">49</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#117">117</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#182">182</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#230">230</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#232">232</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#238">238</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241">241</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#242">242</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#259">259</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#264">264</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#266">266</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#271">271</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#272">272</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#273">273</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#275">275</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#281">281</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#284">284</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#285">285</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#286">286</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#288">288</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#292">292</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#295">295</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#297">297</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#298">298</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#301">301</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#303">303</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#306">306</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#307">307</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#308">308</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#312">312</a> |
| to Ready. |
| |
| Closed issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#111">111</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#277">277</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#279">279</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#287">287</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#289">289</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#293">293</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#302">302</a> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#313">313</a> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#314">314</a> |
| as NAD. |
| |
| </li> |
| <li>R17: |
| Pre-Copenhagen mailing. Converted issues list to XML. Added proposed |
| resolutions for issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#49">49</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#76">76</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#91">91</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#235">235</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#267">267</a>. |
| Added new issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#278">278</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#311">311</a>. |
| </li> |
| <li>R16: |
| post-Toronto mailing; reflects actions taken in Toronto. Added new |
| issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#265">265</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#277">277</a>. Changed status of issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#3">3</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#8">8</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#9">9</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#19">19</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#26">26</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#31">31</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#61">61</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#63">63</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#86">86</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#108">108</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#114">114</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#115">115</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#122">122</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#127">127</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#129">129</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#134">134</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#137">137</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#142">142</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#144">144</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#146">146</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#147">147</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#159">159</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#164">164</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#170">170</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#181">181</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199">199</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#208">208</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#209">209</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#210">210</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#211">211</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#212">212</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#217">217</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#220">220</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#222">222</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#223">223</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#224">224</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a> to "DR". Reopened issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#23">23</a>. Reopened |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#187">187</a>. Changed issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#2">2</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> to NAD. Fixed a typo in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#17">17</a>. Fixed |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#70">70</a>: signature should be changed both places it |
| appears. Fixed issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#160">160</a>: previous version didn't fix |
| the bug in enough places. |
| </li> |
| <li>R15: |
| pre-Toronto mailing. Added issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233">233</a>-<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#264">264</a>. Some small HTML formatting |
| changes so that we pass Weblint tests. |
| </li> |
| <li>R14: |
| post-Tokyo II mailing; reflects committee actions taken in |
| Tokyo. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#232">232</a>. (00-0019R1/N1242) |
| </li> |
| <li>R13: |
| pre-Tokyo II updated: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#212">212</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a>. |
| </li> |
| <li>R12: |
| pre-Tokyo II mailing: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#199">199</a> to |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#211">211</a>. Added "and paragraph 5" to the proposed resolution |
| of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#29">29</a>. Add further rationale to issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#178">178</a>. |
| </li> |
| <li>R11: |
| post-Kona mailing: Updated to reflect LWG and full committee actions |
| in Kona (99-0048/N1224). Note changed resolution of issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#38">38</a>. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#196">196</a> |
| to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#198">198</a>. Closed issues list split into "defects" and |
| "closed" documents. Changed the proposed resolution of issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#4">4</a> to NAD, and changed the wording of proposed resolution |
| of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#38">38</a>. |
| </li> |
| <li>R10: |
| pre-Kona updated. Added proposed resolutions <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#83">83</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#86">86</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#91">91</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#92">92</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a>. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#190">190</a> to |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#195">195</a>. (99-0033/D1209, 14 Oct 99) |
| </li> |
| <li>R9: |
| pre-Kona mailing. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a> to |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#189">189</a>. Issues list split into separate "active" and |
| "closed" documents. (99-0030/N1206, 25 Aug 99) |
| </li> |
| <li>R8: |
| post-Dublin mailing. Updated to reflect LWG and full committee actions |
| in Dublin. (99-0016/N1193, 21 Apr 99) |
| </li> |
| <li>R7: |
| pre-Dublin updated: Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#131">131</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#132">132</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#133">133</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#134">134</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#135">135</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#136">136</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#137">137</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#138">138</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#139">139</a> (31 Mar 99) |
| </li> |
| <li>R6: |
| pre-Dublin mailing. Added issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#127">127</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#128">128</a>, |
| and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#129">129</a>. (99-0007/N1194, 22 Feb 99) |
| </li> |
| <li>R5: |
| update issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>; added issues |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#114">114</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#126">126</a>. Format revisions to prepare |
| for making list public. (30 Dec 98) |
| </li> |
| <li>R4: |
| post-Santa Cruz II updated: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#110">110</a>, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#111">111</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#112">112</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#113">113</a> added, several |
| issues corrected. (22 Oct 98) |
| </li> |
| <li>R3: |
| post-Santa Cruz II: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#94">94</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#109">109</a> |
| added, many issues updated to reflect LWG consensus (12 Oct 98) |
| </li> |
| <li>R2: |
| pre-Santa Cruz II: Issues <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a> to <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#93">93</a> added, |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#17">17</a> updated. (29 Sep 98) |
| </li> |
| <li>R1: |
| Correction to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#55">55</a> resolution, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#60">60</a> code |
| format, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#64">64</a> title. (17 Sep 98) |
| </li> |
| </ul> |
| |
| <h2>Defect Reports</h2> |
| <hr> |
| <h3><a name="1"></a>1. C library linkage editing oversight</h3> |
| <p><b>Section:</b> 17.4.2.2 [using.linkage] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 1997-11-16</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The change specified in the proposed resolution below did not make |
| it into the Standard. This change was accepted in principle at the |
| London meeting, and the exact wording below was accepted at the |
| Morristown meeting.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 17.4.2.2 [using.linkage] paragraph 2 |
| from:</p> |
| |
| <blockquote> |
| <p>It is unspecified whether a name from the Standard C library |
| declared with external linkage has either extern "C" or |
| extern "C++" linkage.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Whether a name from the Standard C library declared with external |
| linkage has extern "C" or extern "C++" linkage |
| is implementation defined. It is recommended that an implementation |
| use extern "C++" linkage for this purpose.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="3"></a>3. Atexit registration during atexit() call is not described</h3> |
| <p><b>Section:</b> 18.4 [support.start.term] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 1997-12-12</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>We appear not to have covered all the possibilities of |
| exit processing with respect to |
| atexit registration. <br> |
| <br> |
| Example 1: (C and C++)</p> |
| |
| <pre> #include <stdlib.h> |
| void f1() { } |
| void f2() { atexit(f1); } |
| |
| int main() |
| { |
| atexit(f2); // the only use of f2 |
| return 0; // for C compatibility |
| }</pre> |
| |
| <p>At program exit, f2 gets called due to its registration in |
| main. Running f2 causes f1 to be newly registered during the exit |
| processing. Is this a valid program? If so, what are its |
| semantics?</p> |
| |
| <p> |
| Interestingly, neither the C standard, nor the C++ draft standard nor |
| the forthcoming C9X Committee Draft says directly whether you can |
| register a function with atexit during exit processing.</p> |
| |
| <p> |
| All 3 standards say that functions are run in reverse order of their |
| registration. Since f1 is registered last, it ought to be run first, |
| but by the time it is registered, it is too late to be first.</p> |
| |
| <p>If the program is valid, the standards are self-contradictory about |
| its semantics.</p> |
| |
| <p>Example 2: (C++ only)</p> |
| |
| <pre> |
| void F() { static T t; } // type T has a destructor |
| |
| int main() |
| { |
| atexit(F); // the only use of F |
| } |
| </pre> |
| |
| <p>Function F registered with atexit has a local static variable t, |
| and F is called for the first time during exit processing. A local |
| static object is initialized the first time control flow passes |
| through its definition, and all static objects are destroyed during |
| exit processing. Is the code valid? If so, what are its semantics?</p> |
| |
| <p> |
| Section 18.3 "Start and termination" says that if a function |
| F is registered with atexit before a static object t is initialized, F |
| will not be called until after t's destructor completes.</p> |
| |
| <p> |
| In example 2, function F is registered with atexit before its local |
| static object O could possibly be initialized. On that basis, it must |
| not be called by exit processing until after O's destructor |
| completes. But the destructor cannot be run until after F is called, |
| since otherwise the object could not be constructed in the first |
| place.</p> |
| |
| <p>If the program is valid, the standard is self-contradictory about |
| its semantics.</p> |
| |
| <p>I plan to submit Example 1 as a public comment on the C9X CD, with |
| a recommendation that the results be undefined. (Alternative: make it |
| unspecified. I don't think it is worthwhile to specify the case where |
| f1 itself registers additional functions, each of which registers |
| still more functions.)</p> |
| |
| <p>I think we should resolve the situation in the whatever way the C |
| committee decides. </p> |
| |
| <p>For Example 2, I recommend we declare the results undefined.</p> |
| |
| <p><i>[See reflector message lib-6500 for further discussion.]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change section 18.3/8 from:</p> |
| <blockquote><p> |
| First, objects with static storage duration are destroyed and |
| functions registered by calling atexit are called. Objects with |
| static storage duration are destroyed in the reverse order of the |
| completion of their constructor. (Automatic objects are not |
| destroyed as a result of calling exit().) Functions registered with |
| atexit are called in the reverse order of their registration. A |
| function registered with atexit before an object obj1 of static |
| storage duration is initialized will not be called until obj1's |
| destruction has completed. A function registered with atexit after |
| an object obj2 of static storage duration is initialized will be |
| called before obj2's destruction starts. |
| </p></blockquote> |
| <p>to:</p> |
| <blockquote><p> |
| First, objects with static storage duration are destroyed and |
| functions registered by calling atexit are called. Non-local objects |
| with static storage duration are destroyed in the reverse order of |
| the completion of their constructor. (Automatic objects are not |
| destroyed as a result of calling exit().) Functions registered with |
| atexit are called in the reverse order of their registration, except |
| that a function is called after any previously registered functions |
| that had already been called at the time it was registered. A |
| function registered with atexit before a non-local object obj1 of |
| static storage duration is initialized will not be called until |
| obj1's destruction has completed. A function registered with atexit |
| after a non-local object obj2 of static storage duration is |
| initialized will be called before obj2's destruction starts. A local |
| static object obj3 is destroyed at the same time it would be if a |
| function calling the obj3 destructor were registered with atexit at |
| the completion of the obj3 constructor. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>See 99-0039/N1215, October 22, 1999, by Stephen D. Clamage for the analysis |
| supporting to the proposed resolution.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="5"></a>5. String::compare specification questionable</h3> |
| <p><b>Section:</b> 21.3.6.8 [string::swap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Jack Reeves <b>Date:</b> 1997-12-11</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::swap">issues</a> in [string::swap].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#87">87</a></p> |
| <p><b>Discussion:</b></p> |
| <p>At the very end of the basic_string class definition is the signature: int |
| compare(size_type pos1, size_type n1, const charT* s, size_type n2 = npos) const; In the |
| following text this is defined as: returns |
| basic_string<charT,traits,Allocator>(*this,pos1,n1).compare( |
| basic_string<charT,traits,Allocator>(s,n2); </p> |
| |
| <p>Since the constructor basic_string(const charT* s, size_type n, const Allocator& a |
| = Allocator()) clearly requires that s != NULL and n < npos and further states that it |
| throws length_error if n == npos, it appears the compare() signature above should always |
| throw length error if invoked like so: str.compare(1, str.size()-1, s); where 's' is some |
| null terminated character array. </p> |
| |
| <p>This appears to be a typo since the obvious intent is to allow either the call above or |
| something like: str.compare(1, str.size()-1, s, strlen(s)-1); </p> |
| |
| <p>This would imply that what was really intended was two signatures int compare(size_type |
| pos1, size_type n1, const charT* s) const int compare(size_type pos1, size_type n1, const |
| charT* s, size_type n2) const; each defined in terms of the corresponding constructor. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the compare signature in 21.3 [basic.string] |
| (at the very end of the basic_string synopsis) which reads:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos1, size_type n1,<br> |
| const charT* s, |
| size_type n2 = npos) const;</tt></p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos1, size_type n1,<br> |
| const charT* s) const;<br> |
| int compare(size_type pos1, size_type n1,<br> |
| const charT* s, |
| size_type n2) const;</tt></p> |
| </blockquote> |
| |
| <p>Replace the portion of 21.3.6.8 [string::swap] |
| paragraphs 5 and 6 which read:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos, size_type n1,<br> |
| charT * s, size_type n2 |
| = npos) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s, n2))</tt></p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>int compare(size_type pos, size_type n1,<br> |
| const charT * s) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s ))<br> |
| <br> |
| int compare(size_type pos, size_type n1,<br> |
| const charT * s, |
| size_type n2) const;<br> |
| </tt>Returns:<tt><br> |
| basic_string<charT,traits,Allocator>(*this, pos, n1).compare(<br> |
| |
| basic_string<charT,traits,Allocator>( s, n2))</tt></p> |
| </blockquote> |
| |
| <p>Editors please note that in addition to splitting the signature, the third argument |
| becomes const, matching the existing synopsis.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>While the LWG dislikes adding signatures, this is a clear defect in |
| the Standard which must be fixed. The same problem was also |
| identified in issues 7 (item 5) and 87.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="7"></a>7. String clause minor problems</h3> |
| <p><b>Section:</b> 21 [strings] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1997-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#strings">issues</a> in [strings].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>(1) In 21.3.6.4 [string::insert], the description of template |
| <class InputIterator> insert(iterator, InputIterator, |
| InputIterator) makes no sense. It refers to a member function that |
| doesn't exist. It also talks about the return value of a void |
| function. </p> |
| |
| <p>(2) Several versions of basic_string::replace don't appear in the |
| class synopsis. </p> |
| |
| <p>(3) basic_string::push_back appears in the synopsis, but is never |
| described elsewhere. In the synopsis its argument is const charT, |
| which doesn't makes much sense; it should probably be charT, or |
| possible const charT&. </p> |
| |
| <p>(4) basic_string::pop_back is missing. </p> |
| |
| <p>(5) int compare(size_type pos, size_type n1, charT* s, size_type n2 |
| = npos) make no sense. First, it's const charT* in the synopsis and |
| charT* in the description. Second, given what it says in RETURNS, |
| leaving out the final argument will always result in an exception |
| getting thrown. This is paragraphs 5 and 6 of |
| 21.3.6.8 [string::swap]</p> |
| |
| <p>(6) In table 37, in section 21.1.1 [char.traits.require], |
| there's a note for X::move(s, p, n). It says "Copies correctly |
| even where p is in [s, s+n)". This is correct as far as it goes, |
| but it doesn't go far enough; it should also guarantee that the copy |
| is correct even where s in in [p, p+n). These are two orthogonal |
| guarantees, and neither one follows from the other. Both guarantees |
| are necessary if X::move is supposed to have the same sort of |
| semantics as memmove (which was clearly the intent), and both |
| guarantees are necessary if X::move is actually supposed to be |
| useful. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>ITEM 1: In 21.3.5.4 [lib.string::insert], change paragraph 16 to <br> |
| <br> |
| EFFECTS: Equivalent to insert(p - begin(), basic_string(first, last)).<br> |
| <br> |
| ITEM 2: Not a defect; the Standard is clear.. There are ten versions of replace() in |
| the synopsis, and ten versions in 21.3.5.6 [lib.string::replace].<br> |
| <br> |
| ITEM 3: Change the declaration of push_back in the string synopsis (21.3, |
| [lib.basic.string]) from:</p> |
| |
| <p> void push_back(const charT)<br> |
| <br> |
| to<br> |
| <br> |
| void push_back(charT)<br> |
| <br> |
| Add the following text immediately after 21.3.5.2 [lib.string::append], paragraph 10.<br> |
| <br> |
| void basic_string::push_back(charT c);<br> |
| EFFECTS: Equivalent to append(static_cast<size_type>(1), c);<br> |
| <br> |
| ITEM 4: Not a defect. The omission appears to have been deliberate.<br> |
| <br> |
| ITEM 5: Duplicate; see issue 5 (and 87).<br> |
| <br> |
| ITEM 6: In table 37, Replace:<br> |
| <br> |
| "Copies correctly even where p is in [s, s+n)."<br> |
| <br> |
| with:<br> |
| <br> |
| "Copies correctly even where the ranges [p, p+n) and [s, |
| s+n) overlap."</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="8"></a>8. Locale::global lacks guarantee</h3> |
| <p><b>Section:</b> 22.1.1.5 [locale.statics] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1997-12-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>It appears there's an important guarantee missing from clause |
| 22. We're told that invoking locale::global(L) sets the C locale if L |
| has a name. However, we're not told whether or not invoking |
| setlocale(s) sets the global C++ locale. </p> |
| |
| <p>The intent, I think, is that it should not, but I can't find any |
| such words anywhere. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a sentence at the end of 22.1.1.5 [locale.statics], |
| paragraph 2: </p> |
| |
| <blockquote> |
| <p>No library function other than <tt>locale::global()</tt> shall affect |
| the value returned by <tt>locale()</tt>. </p> |
| |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="9"></a>9. Operator new(0) calls should not yield the same pointer</h3> |
| <p><b>Section:</b> 18.5.1 [new.delete] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 1998-01-04</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Scott Meyers, in a comp.std.c++ posting: I just noticed that |
| section 3.7.3.1 of CD2 seems to allow for the possibility that all |
| calls to operator new(0) yield the same pointer, an implementation |
| technique specifically prohibited by ARM 5.3.3.Was this prohibition |
| really lifted? Does the FDIS agree with CD2 in the regard? [Issues |
| list maintainer's note: the IS is the same.]</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the last paragraph of 3.7.3 from:</p> |
| <blockquote> |
| <p>Any allocation and/or deallocation functions defined in a C++ program shall |
| conform to the semantics specified in 3.7.3.1 and 3.7.3.2.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Any allocation and/or deallocation functions defined in a C++ program, |
| including the default versions in the library, shall conform to the semantics |
| specified in 3.7.3.1 and 3.7.3.2.</p> |
| </blockquote> |
| <p>Change 3.7.3.1/2, next-to-last sentence, from :</p> |
| <blockquote> |
| <p>If the size of the space requested is zero, the value returned shall not be |
| a null pointer value (4.10).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Even if the size of the space requested is zero, the request can fail. If |
| the request succeeds, the value returned shall be a non-null pointer value |
| (4.10) p0 different from any previously returned value p1, unless that value |
| p1 was since passed to an operator delete.</p> |
| </blockquote> |
| <p>5.3.4/7 currently reads:</p> |
| <blockquote> |
| <p>When the value of the expression in a direct-new-declarator is zero, the |
| allocation function is called to allocate an array with no elements. The |
| pointer returned by the new-expression is non-null. [Note: If the library |
| allocation function is called, the pointer returned is distinct from the |
| pointer to any other object.]</p> |
| </blockquote> |
| <p>Retain the first sentence, and delete the remainder.</p> |
| <p>18.5.1 currently has no text. Add the following:</p> |
| <blockquote> |
| <p>Except where otherwise specified, the provisions of 3.7.3 apply to the |
| library versions of operator new and operator delete.</p> |
| </blockquote> |
| <p>To 18.5.1.3, add the following text:</p> |
| <blockquote> |
| <p>The provisions of 3.7.3 do not apply to these reserved placement forms of |
| operator new and operator delete.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>See 99-0040/N1216, October 22, 1999, by Stephen D. Clamage for the analysis |
| supporting to the proposed resolution.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="11"></a>11. Bitset minor problems</h3> |
| <p><b>Section:</b> 23.3.5 [template.bitset] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-01-22</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#template.bitset">issues</a> in [template.bitset].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>(1) bitset<>::operator[] is mentioned in the class synopsis (23.3.5), but it is |
| not documented in 23.3.5.2. </p> |
| |
| <p>(2) The class synopsis only gives a single signature for bitset<>::operator[], |
| reference operator[](size_t pos). This doesn't make much sense. It ought to be overloaded |
| on const. reference operator[](size_t pos); bool operator[](size_t pos) const. </p> |
| |
| <p>(3) Bitset's stream input function (23.3.5.3) ought to skip all whitespace before |
| trying to extract 0s and 1s. The standard doesn't explicitly say that, though. This should |
| go in the Effects clause.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>ITEMS 1 AND 2:<br> |
| <br> |
| In the bitset synopsis (23.3.5 [template.bitset]), |
| replace the member function <br> |
| <br> |
| <tt> reference operator[](size_t pos);<br> |
| </tt><br> |
| with the two member functions<br> |
| <br> |
| <tt> bool operator[](size_t pos) const; <br> |
| reference operator[](size_t pos); <br> |
| </tt><br> |
| Add the following text at the end of 23.3.5.2 [bitset.members], |
| immediately after paragraph 45:</p> |
| |
| <blockquote> |
| <p><tt>bool operator[](size_t pos) const;</tt><br> |
| Requires: pos is valid<br> |
| Throws: nothing<br> |
| Returns: <tt>test(pos)</tt><br> |
| <br> |
| <tt>bitset<N>::reference operator[](size_t pos);</tt> <br> |
| Requires: pos is valid<br> |
| Throws: nothing<br> |
| Returns: An object of type <tt>bitset<N>::reference</tt> such that <tt>(*this)[pos] |
| == this->test(pos)</tt>, and such that <tt>(*this)[pos] = val</tt> is equivalent to <tt>this->set(pos, |
| val);</tt></p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes Item 3 is not a defect. "Formatted |
| input" implies the desired semantics. See 27.6.1.2 [istream.formatted]. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="13"></a>13. Eos refuses to die</h3> |
| <p><b>Section:</b> 27.6.1.2.3 [istream::extractors] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> William M. Miller <b>Date:</b> 1998-03-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::extractors">issues</a> in [istream::extractors].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 27.6.1.2.3, there is a reference to "eos", which is |
| the only one in the whole draft (at least using Acrobat search), so |
| it's undefined. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.2.3 [istream::extractors], replace "eos" with |
| "charT()"</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="14"></a>14. Locale::combine should be const</h3> |
| <p><b>Section:</b> 22.1.1.3 [locale.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.members">issues</a> in [locale.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>locale::combine is the only member function of locale (other than constructors and |
| destructor) that is not const. There is no reason for it not to be const, and good reasons |
| why it should have been const. Furthermore, leaving it non-const conflicts with 22.1.1 |
| paragraph 6: "An instance of a locale is immutable." </p> |
| |
| <p>History: this member function originally was a constructor. it happened that the |
| interface it specified had no corresponding language syntax, so it was changed to a member |
| function. As constructors are never const, there was no "const" in the interface |
| which was transformed into member "combine". It should have been added at that |
| time, but the omission was not noticed. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 [locale] and also in 22.1.1.3 [locale.members], add |
| "const" to the declaration of member combine: </p> |
| <blockquote> |
| <pre>template <class Facet> locale combine(const locale& other) const; </pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="15"></a>15. Locale::name requirement inconsistent</h3> |
| <p><b>Section:</b> 22.1.1.3 [locale.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.members">issues</a> in [locale.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>locale::name() is described as returning a string that can be passed to a locale |
| constructor, but there is no matching constructor. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1.3 [locale.members], paragraph 5, replace |
| "<tt>locale(name())</tt>" with |
| "<tt>locale(name().c_str())</tt>". |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="16"></a>16. Bad ctype_byname<char> decl</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The new virtual members ctype_byname<char>::do_widen and do_narrow did not get |
| edited in properly. Instead, the member do_widen appears four times, with wrong argument |
| lists. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>The correct declarations for the overloaded members |
| <tt>do_narrow</tt> and <tt>do_widen</tt> should be copied |
| from 22.2.1.3 [facet.ctype.special].</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="17"></a>17. Bad bool parsing</h3> |
| <p><b>Section:</b> 22.2.2.1.2 [facet.num.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>This section describes the process of parsing a text boolean value from the input |
| stream. It does not say it recognizes either of the sequences "true" or |
| "false" and returns the corresponding bool value; instead, it says it recognizes |
| only one of those sequences, and chooses which according to the received value of a |
| reference argument intended for returning the result, and reports an error if the other |
| sequence is found. (!) Furthermore, it claims to get the names from the ctype<> |
| facet rather than the numpunct<> facet, and it examines the "boolalpha" |
| flag wrongly; it doesn't define the value "loc"; and finally, it computes |
| wrongly whether to use numeric or "alpha" parsing.<br> |
| <br> |
| I believe the correct algorithm is "as if": </p> |
| |
| <pre> // in, err, val, and str are arguments. |
| err = 0; |
| const numpunct<charT>& np = use_facet<numpunct<charT> >(str.getloc()); |
| const string_type t = np.truename(), f = np.falsename(); |
| bool tm = true, fm = true; |
| size_t pos = 0; |
| while (tm && pos < t.size() || fm && pos < f.size()) { |
| if (in == end) { err = str.eofbit; } |
| bool matched = false; |
| if (tm && pos < t.size()) { |
| if (!err && t[pos] == *in) matched = true; |
| else tm = false; |
| } |
| if (fm && pos < f.size()) { |
| if (!err && f[pos] == *in) matched = true; |
| else fm = false; |
| } |
| if (matched) { ++in; ++pos; } |
| if (pos > t.size()) tm = false; |
| if (pos > f.size()) fm = false; |
| } |
| if (tm == fm || pos == 0) { err |= str.failbit; } |
| else { val = tm; } |
| return in;</pre> |
| |
| <p>Notice this works reasonably when the candidate strings are both empty, or equal, or |
| when one is a substring of the other. The proposed text below captures the logic of the |
| code above.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.2 [facet.num.get.virtuals], in the first line of paragraph 14, |
| change "&&" to "&".</p> |
| |
| <p>Then, replace paragraphs 15 and 16 as follows:</p> |
| |
| <blockquote> |
| |
| <p>Otherwise target sequences are determined "as if" by |
| calling the members <tt>falsename()</tt> and |
| <tt>truename()</tt> of the facet obtained by |
| <tt>use_facet<numpunct<charT> >(str.getloc())</tt>. |
| Successive characters in the range <tt>[in,end)</tt> (see |
| [lib.sequence.reqmts]) are obtained and matched against |
| corresponding positions in the target sequences only as necessary to |
| identify a unique match. The input iterator <tt>in</tt> is |
| compared to <tt>end</tt> only when necessary to obtain a |
| character. If and only if a target sequence is uniquely matched, |
| <tt>val</tt> is set to the corresponding value.</p> |
| |
| </blockquote> |
| |
| <blockquote> |
| <p>The <tt>in</tt> iterator is always left pointing one position beyond the last character |
| successfully matched. If <tt>val</tt> is set, then err is set to <tt>str.goodbit</tt>; or to |
| <tt>str.eofbit</tt> if, when seeking another character to match, it is found that |
| <tt>(in==end)</tt>. If <tt>val</tt> is not set, then <i>err</i> is set to <tt>str.failbit</tt>; or to |
| <tt>(str.failbit|str.eofbit)</tt>if |
| the reason for the failure was that <tt>(in==end)</tt>. [Example: for targets |
| <tt>true</tt>:"a" and <tt>false</tt>:"abb", the input sequence "a" yields |
| <tt>val==true</tt> and <tt>err==str.eofbit</tt>; the input sequence "abc" yields |
| <tt>err=str.failbit</tt>, with <tt>in</tt> ending at the 'c' element. For targets |
| <tt>true</tt>:"1" |
| and <tt>false</tt>:"0", the input sequence "1" yields <tt>val==true</tt> |
| and <tt>err=str.goodbit</tt>. For empty targets (""), any input sequence yields |
| <tt>err==str.failbit</tt>. --end example]</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="18"></a>18. Get(...bool&) omitted</h3> |
| <p><b>Section:</b> 22.2.2.1.1 [facet.num.get.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.members">issues</a> in [facet.num.get.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In the list of num_get<> non-virtual members on page 22-23, the member |
| that parses bool values was omitted from the list of definitions of non-virtual |
| members, though it is listed in the class definition and the corresponding |
| virtual is listed everywhere appropriate. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add at the beginning of 22.2.2.1.1 [facet.num.get.members] |
| another get member for bool&, copied from the entry in |
| 22.2.2.1 [locale.num.get].</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="19"></a>19. "Noconv" definition too vague</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#10">10</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the definitions of codecvt<>::do_out and do_in, they are |
| specified to return noconv if "no conversion is |
| needed". This definition is too vague, and does not say |
| normatively what is done with the buffers. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the entry for noconv in the table under paragraph 4 in section |
| 22.2.1.4.2 [locale.codecvt.virtuals] to read: |
| </p> |
| <blockquote> |
| <p><tt>noconv</tt>: <tt>internT</tt> and <tt>externT</tt> are the same type, |
| and input sequence is identical to converted sequence.</p> |
| </blockquote> |
| <p>Change the Note in paragraph 2 to normative text as follows:</p> |
| <blockquote> |
| <p>If returns <tt>noconv</tt>, <tt>internT</tt> and <tt>externT</tt> are the |
| same type and the converted sequence is identical to the input sequence <tt>[from,from_next)</tt>. |
| <tt>to_next</tt> is set equal to <tt>to</tt>, the value of <tt>state</tt> is |
| unchanged, and there are no changes to the values in <tt>[to, to_limit)</tt>.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="20"></a>20. Thousands_sep returns wrong type</h3> |
| <p><b>Section:</b> 22.2.3.1.2 [facet.numpunct.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The synopsis for numpunct<>::do_thousands_sep, and the |
| definition of numpunct<>::thousands_sep which calls it, specify |
| that it returns a value of type char_type. Here it is erroneously |
| described as returning a "string_type". </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.3.1.2 [facet.numpunct.virtuals], above paragraph 2, change |
| "string_type" to "char_type". </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="21"></a>21. Codecvt_byname<> instantiations</h3> |
| <p><b>Section:</b> 22.1.1.1.1 [locale.category] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.category">issues</a> in [locale.category].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In the second table in the section, captioned "Required |
| instantiations", the instantiations for codecvt_byname<> |
| have been omitted. These are necessary to allow users to construct a |
| locale by name from facets. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add in 22.1.1.1.1 [locale.category] to the table captioned |
| "Required instantiations", in the category "ctype" |
| the lines </p> |
| |
| <blockquote> |
| <pre>codecvt_byname<char,char,mbstate_t>, |
| codecvt_byname<wchar_t,char,mbstate_t> </pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="22"></a>22. Member open vs. flags</h3> |
| <p><b>Section:</b> 27.8.1.9 [ifstream.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ifstream.members">issues</a> in [ifstream.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description of basic_istream<>::open leaves unanswered questions about how it |
| responds to or changes flags in the error status for the stream. A strict reading |
| indicates that it ignores the bits and does not change them, which confuses users who do |
| not expect eofbit and failbit to remain set after a successful open. There are three |
| reasonable resolutions: 1) status quo 2) fail if fail(), ignore eofbit 3) clear failbit |
| and eofbit on call to open(). </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.9 [ifstream.members] paragraph 3, <i>and</i> in 27.8.1.13 [ofstream.members] paragraph 3, under open() effects, add a footnote: |
| </p> |
| |
| <blockquote> |
| <p>A successful open does not change the error state.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This may seem surprising to some users, but it's just an instance |
| of a general rule: error flags are never cleared by the |
| implementation. The only way error flags are are ever cleared is if |
| the user explicitly clears them by hand.</p> |
| |
| <p>The LWG believed that preserving this general rule was |
| important enough so that an exception shouldn't be made just for this |
| one case. The resolution of this issue clarifies what the LWG |
| believes to have been the original intent.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="24"></a>24. "do_convert" doesn't exist</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#72">72</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The description of codecvt<>::do_out and do_in mentions a |
| symbol "do_convert" which is not defined in the |
| standard. This is a leftover from an edit, and should be "do_in |
| and do_out". </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.1.4 [locale.codecvt], paragraph 3, change |
| "do_convert" to "do_in or do_out". Also, in 22.2.1.4.2 [locale.codecvt.virtuals], change "do_convert()" to "do_in |
| or do_out". </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="25"></a>25. String operator<< uses width() value wrong</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#67">67</a></p> |
| <p><b>Discussion:</b></p> |
| <p>In the description of operator<< applied to strings, the standard says that uses |
| the smaller of os.width() and str.size(), to pad "as described in stage 3" |
| elsewhere; but this is inconsistent, as this allows no possibility of space for padding. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 21.3.8.9 [string.io] paragraph 4 from:<br> |
| <br> |
| "... where <tt>n</tt> is the smaller of <tt>os.width()</tt> and <tt>str.size()</tt>; |
| ..."<br> |
| <br> |
| to: <br> |
| <br> |
| "... where <tt>n</tt> is the larger of <tt>os.width()</tt> and <tt>str.size()</tt>; |
| ..."</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="26"></a>26. Bad sentry example</h3> |
| <p><b>Section:</b> 27.6.1.1.3 [istream::sentry] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::sentry">issues</a> in [istream::sentry].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In paragraph 6, the code in the example: </p> |
| |
| <pre> template <class charT, class traits = char_traits<charT> > |
| basic_istream<charT,traits>::sentry( |
| basic_istream<charT,traits>& is, bool noskipws = false) { |
| ... |
| int_type c; |
| typedef ctype<charT> ctype_type; |
| const ctype_type& ctype = use_facet<ctype_type>(is.getloc()); |
| while ((c = is.rdbuf()->snextc()) != traits::eof()) { |
| if (ctype.is(ctype.space,c)==0) { |
| is.rdbuf()->sputbackc (c); |
| break; |
| } |
| } |
| ... |
| }</pre> |
| |
| <p>fails to demonstrate correct use of the facilities described. In |
| particular, it fails to use traits operators, and specifies incorrect |
| semantics. (E.g. it specifies skipping over the first character in the |
| sequence without examining it.) </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the example above from 27.6.1.1.3 [istream::sentry] |
| paragraph 6.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The originally proposed replacement code for the example was not |
| correct. The LWG tried in Kona and again in Tokyo to correct it |
| without success. In Tokyo, an implementor reported that actual working |
| code ran over one page in length and was quite complicated. The LWG |
| decided that it would be counter-productive to include such a lengthy |
| example, which might well still contain errors.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="27"></a>27. String::erase(range) yields wrong iterator</h3> |
| <p><b>Section:</b> 21.3.6.5 [string::erase] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::erase">issues</a> in [string::erase].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The string::erase(iterator first, iterator last) is specified to return an element one |
| place beyond the next element after the last one erased. E.g. for the string |
| "abcde", erasing the range ['b'..'d') would yield an iterator for element 'e', |
| while 'd' has not been erased. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.6.5 [string::erase], paragraph 10, change: </p> |
| |
| <blockquote> |
| <p>Returns: an iterator which points to the element immediately following _last_ prior to |
| the element being erased. </p> |
| </blockquote> |
| |
| <p>to read </p> |
| |
| <blockquote> |
| <p>Returns: an iterator which points to the element pointed to by _last_ prior to the |
| other elements being erased. </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="28"></a>28. Ctype<char>is ambiguous</h3> |
| <p><b>Section:</b> 22.2.1.3.2 [facet.ctype.char.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.ctype.char.members">issues</a> in [facet.ctype.char.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#236">236</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The description of the vector form of ctype<char>::is can be interpreted to mean |
| something very different from what was intended. Paragraph 4 says </p> |
| |
| <blockquote> |
| <p>Effects: The second form, for all *p in the range [low, high), assigns vec[p-low] to |
| table()[(unsigned char)*p]. </p> |
| </blockquote> |
| |
| <p>This is intended to copy the value indexed from table()[] into the place identified in |
| vec[]. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 22.2.1.3.2 [facet.ctype.char.members], paragraph 4, to read </p> |
| |
| <blockquote> |
| <p>Effects: The second form, for all *p in the range [low, high), assigns into vec[p-low] |
| the value table()[(unsigned char)*p]. </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="29"></a>29. Ios_base::init doesn't exist</h3> |
| <p><b>Section:</b> 27.3.1 [narrow.stream.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#narrow.stream.objects">issues</a> in [narrow.stream.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Sections 27.3.1 [narrow.stream.objects] and 27.3.2 [wide.stream.objects] mention |
| a function ios_base::init, which is not defined. Probably they mean |
| basic_ios<>::init, defined in 27.4.4.1 [basic.ios.cons], |
| paragraph 3. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>[R12: modified to include paragraph 5.]</p> |
| |
| <p>In 27.3.1 [narrow.stream.objects] paragraph 2 and 5, change </p> |
| |
| <blockquote> |
| <p>ios_base::init </p> |
| </blockquote> |
| |
| <p>to </p> |
| |
| <blockquote> |
| <p>basic_ios<char>::init </p> |
| </blockquote> |
| |
| <p>Also, make a similar change in 27.3.2 [wide.stream.objects] except it |
| should read </p> |
| |
| <blockquote> |
| <p>basic_ios<wchar_t>::init </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="30"></a>30. Wrong header for LC_*</h3> |
| <p><b>Section:</b> 22.1.1.1.1 [locale.category] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.category">issues</a> in [locale.category].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 2 implies that the C macros LC_CTYPE etc. are defined in <cctype>, |
| where they are in fact defined elsewhere to appear in <clocale>. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1.1.1 [locale.category], paragraph 2, change |
| "<cctype>" to read "<clocale>". </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="31"></a>31. Immutable locale values</h3> |
| <p><b>Section:</b> 22.1.1 [locale] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale">issues</a> in [locale].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#378">378</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 6, says "An instance of <tt>locale</tt> is |
| <i>immutable</i>; once a facet reference is obtained from it, |
| ...". This has caused some confusion, because locale variables |
| are manifestly assignable. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 [locale] replace paragraph 6</p> |
| |
| <blockquote> |
| <p>An instance of <tt>locale</tt> is immutable; once a facet |
| reference is obtained from it, that reference remains usable as long |
| as the locale value itself exists.</p> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p>Once a facet reference is obtained from a locale object by |
| calling use_facet<>, that reference remains usable, and the |
| results from member functions of it may be cached and re-used, as |
| long as some locale object refers to that facet.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="32"></a>32. Pbackfail description inconsistent</h3> |
| <p><b>Section:</b> 27.5.2.4.4 [streambuf.virt.pback] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description of the required state before calling virtual member |
| basic_streambuf<>::pbackfail requirements is inconsistent with the conditions |
| described in 27.5.2.2.4 [lib.streambuf.pub.pback] where member sputbackc calls it. |
| Specifically, the latter says it calls pbackfail if: </p> |
| |
| <p> traits::eq(c,gptr()[-1]) is false </p> |
| |
| <p>where pbackfail claims to require: </p> |
| |
| <p> traits::eq(*gptr(),traits::to_char_type(c)) returns false </p> |
| |
| <p>It appears that the pbackfail description is wrong. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.5.2.4.4 [streambuf.virt.pback], paragraph 1, change:</p> |
| |
| <blockquote> |
| <p>"<tt>traits::eq(*gptr(),traits::to_char_type( c))</tt>"</p> |
| </blockquote> |
| |
| <p>to </p> |
| |
| <blockquote> |
| <p>"<tt>traits::eq(traits::to_char_type(c),gptr()[-1])</tt>" |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Note deliberate reordering of arguments for clarity in addition to the correction of |
| the argument value.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="33"></a>33. Codecvt<> mentions from_type</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#43">43</a></p> |
| <p><b>Discussion:</b></p> |
| <p>In the table defining the results from do_out and do_in, the specification for the |
| result <i>error</i> says </p> |
| |
| <blockquote> |
| <p>encountered a from_type character it could not convert </p> |
| </blockquote> |
| |
| <p>but from_type is not defined. This clearly is intended to be an externT for do_in, or |
| an internT for do_out. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.1.4.2 [locale.codecvt.virtuals] paragraph 4, replace the definition |
| in the table for the case of _error_ with </p> |
| |
| <blockquote> |
| <p>encountered a character in <tt>[from,from_end)</tt> that it could not convert. </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="34"></a>34. True/falsename() not in ctype<></h3> |
| <p><b>Section:</b> 22.2.2.2.2 [facet.num.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.put.virtuals">issues</a> in [facet.num.put.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In paragraph 19, Effects:, members truename() and falsename are used from facet |
| ctype<charT>, but it has no such members. Note that this is also a problem in |
| 22.2.2.1.2, addressed in (4). </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.2.2 [facet.num.put.virtuals], paragraph 19, in the Effects: |
| clause for member put(...., bool), replace the initialization of the |
| string_type value s as follows: </p> |
| |
| <blockquote> |
| <pre>const numpunct& np = use_facet<numpunct<charT> >(loc); |
| string_type s = val ? np.truename() : np.falsename(); </pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="35"></a>35. No manipulator unitbuf in synopsis</h3> |
| <p><b>Section:</b> 27.4 [iostreams.base] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 27.4.5.1 [fmtflags.manip], we have a definition for a manipulator |
| named "unitbuf". Unlike other manipulators, it's not listed |
| in synopsis. Similarly for "nounitbuf". </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the synopsis for <ios> in 27.4 [iostreams.base], after |
| the entry for "nouppercase", the prototypes: </p> |
| |
| <blockquote> |
| <pre>ios_base& unitbuf(ios_base& str); |
| ios_base& nounitbuf(ios_base& str); </pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="36"></a>36. Iword & pword storage lifetime omitted</h3> |
| <p><b>Section:</b> 27.4.2.5 [ios.base.storage] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base.storage">issues</a> in [ios.base.storage].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In the definitions for ios_base::iword and pword, the lifetime of the storage is |
| specified badly, so that an implementation which only keeps the last value stored appears |
| to conform. In particular, it says: </p> |
| |
| <p>The reference returned may become invalid after another call to the object's iword |
| member with a different index ... </p> |
| |
| <p>This is not idle speculation; at least one implementation was done this way. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add in 27.4.2.5 [ios.base.storage], in both paragraph 2 and also in |
| paragraph 4, replace the sentence: </p> |
| |
| <blockquote> |
| <p>The reference returned may become invalid after another call to the object's iword |
| [pword] member with a different index, after a call to its copyfmt member, or when the |
| object is destroyed. </p> |
| </blockquote> |
| |
| <p>with: </p> |
| |
| <blockquote> |
| <p>The reference returned is invalid after any other operations on the object. However, |
| the value of the storage referred to is retained, so that until the next call to copyfmt, |
| calling iword [pword] with the same index yields another reference to the same value. </p> |
| </blockquote> |
| |
| <p>substituting "iword" or "pword" as appropriate. </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="37"></a>37. Leftover "global" reference</h3> |
| <p><b>Section:</b> 22.1.1 [locale] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale">issues</a> in [locale].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In the overview of locale semantics, paragraph 4, is the sentence </p> |
| |
| <blockquote> |
| <p>If Facet is not present in a locale (or, failing that, in the global locale), it throws |
| the standard exception bad_cast. </p> |
| </blockquote> |
| |
| <p>This is not supported by the definition of use_facet<>, and represents semantics |
| from an old draft. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1 [locale], paragraph 4, delete the parenthesized |
| expression </p> |
| |
| <blockquote> |
| <p>(or, failing that, in the global locale) </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="38"></a>38. Facet definition incomplete</h3> |
| <p><b>Section:</b> 22.1.2 [locale.global.templates] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>It has been noticed by Esa Pulkkinen that the definition of |
| "facet" is incomplete. In particular, a class derived from |
| another facet, but which does not define a member <i>id</i>, cannot |
| safely serve as the argument <i>F</i> to use_facet<F>(loc), |
| because there is no guarantee that a reference to the facet instance |
| stored in <i>loc</i> is safely convertible to <i>F</i>. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the definition of std::use_facet<>(), replace the text in paragraph 1 which |
| reads: </p> |
| |
| <blockquote> |
| <p>Get a reference to a facet of a locale. </p> |
| </blockquote> |
| |
| <p>with: </p> |
| |
| <blockquote> |
| <p>Requires: <tt>Facet</tt> is a facet class whose definition |
| contains the public static member <tt>id</tt> as defined in 22.1.1.1.2 [locale.facet]. </p> |
| </blockquote> |
| |
| <p><i>[ |
| Kona: strike as overspecification the text "(not inherits)" |
| from the original resolution, which read "... whose definition |
| contains (not inherits) the public static member |
| <tt>id</tt>..." |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="39"></a>39. istreambuf_iterator<>::operator++(int) definition garbled</h3> |
| <p><b>Section:</b> 24.5.3.4 [istreambuf.iterator::op++] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Following the definition of istreambuf_iterator<>::operator++(int) in paragraph |
| 3, the standard contains three lines of garbage text left over from a previous edit. </p> |
| |
| <blockquote> |
| <pre>istreambuf_iterator<charT,traits> tmp = *this; |
| sbuf_->sbumpc(); |
| return(tmp); </pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.3.4 [istreambuf.iterator::op++], delete the three lines of code at the |
| end of paragraph 3. </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="40"></a>40. Meaningless normative paragraph in examples</h3> |
| <p><b>Section:</b> 22.2.8 [facets.examples] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facets.examples">issues</a> in [facets.examples].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 3 of the locale examples is a description of part of an |
| implementation technique that has lost its referent, and doesn't mean |
| anything. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Delete 22.2.8 [facets.examples] paragraph 3 which begins "This |
| initialization/identification system depends...", or (at the |
| editor's option) replace it with a place-holder to keep the paragraph |
| numbering the same. </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="41"></a>41. Ios_base needs clear(), exceptions()</h3> |
| <p><b>Section:</b> 27.4.2 [ios.base] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base">issues</a> in [ios.base].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#157">157</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The description of ios_base::iword() and pword() in 27.4.2.4 [ios.members.static], say that if they fail, they "set badbit, |
| which may throw an exception". However, ios_base offers no |
| interface to set or to test badbit; those interfaces are defined in |
| basic_ios<>. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the description in 27.4.2.5 [ios.base.storage] in |
| paragraph 2, and also in paragraph 4, as follows. Replace</p> |
| |
| <blockquote> |
| <p>If the function fails it sets badbit, which may throw an exception.</p> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p>If the function fails, and <tt>*this</tt> is a base sub-object of |
| a <tt>basic_ios<></tt> object or sub-object, the effect is |
| equivalent to calling <tt>basic_ios<>::setstate(badbit)</tt> |
| on the derived object (which may throw <tt>failure</tt>).</p> |
| </blockquote> |
| |
| <p><i>[Kona: LWG reviewed wording; setstate(failbit) changed to |
| setstate(badbit).]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="42"></a>42. String ctors specify wrong default allocator</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The basic_string<> copy constructor: </p> |
| |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos, const Allocator& a = Allocator()); </pre> |
| |
| <p>specifies an Allocator argument default value that is |
| counter-intuitive. The natural choice for a the allocator to copy from |
| is str.get_allocator(). Though this cannot be expressed in |
| default-argument notation, overloading suffices. </p> |
| |
| <p>Alternatively, the other containers in Clause 23 (deque, list, |
| vector) do not have this form of constructor, so it is inconsistent, |
| and an evident source of confusion, for basic_string<> to have |
| it, so it might better be removed. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> In 21.3 [basic.string], replace the declaration of the copy |
| constructor as follows: </p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str); |
| basic_string(const basic_string& str, size_type pos, size_type n = npos, |
| const Allocator& a = Allocator());</pre> |
| </blockquote> |
| |
| <p>In 21.3.1 [string.require], replace the copy constructor declaration |
| as above. Add to paragraph 5, Effects:</p> |
| |
| <blockquote> |
| <p>In the first form, the Allocator value used is copied from |
| <tt>str.get_allocator()</tt>.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes the constructor is actually broken, rather than |
| just an unfortunate design choice.</p> |
| |
| <p>The LWG considered two other possible resolutions:</p> |
| |
| <p>A. In 21.3 [basic.string], replace the declaration of the copy |
| constructor as follows:</p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos); |
| basic_string(const basic_string& str, size_type pos, |
| size_type n, const Allocator& a); </pre> |
| </blockquote> |
| |
| <p>In 21.3.1 [string.require], replace the copy constructor declaration |
| as above. Add to paragraph 5, Effects: </p> |
| |
| <blockquote> |
| <p>When no <tt>Allocator</tt> argument is provided, the string is constructed using the |
| value <tt>str.get_allocator()</tt>. </p> |
| </blockquote> |
| |
| <p>B. In 21.3 [basic.string], and also in 21.3.1 [string.require], replace |
| the declaration of the copy constructor as follows: </p> |
| |
| <blockquote> |
| <pre>basic_string(const basic_string& str, size_type pos = 0, |
| size_type n = npos); </pre> |
| </blockquote> |
| |
| <p>The proposed resolution reflects the original intent of the LWG. It |
| was also noted by Pete Becker that this fix "will cause |
| a small amount of existing code to now work correctly."</p> |
| |
| <p><i>[ |
| Kona: issue editing snafu fixed - the proposed resolution now correctly |
| reflects the LWG consensus. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="44"></a>44. Iostreams use operator== on int_type values</h3> |
| <p><b>Section:</b> 27 [input.output] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.output">issues</a> in [input.output].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Many of the specifications for iostreams specify that character |
| values or their int_type equivalents are compared using operators == |
| or !=, though in other places traits::eq() or traits::eq_int_type is |
| specified to be used throughout. This is an inconsistency; we should |
| change uses of == and != to use the traits members instead. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Pre-Kona: Dietmar supplied wording]</i></p> |
| |
| |
| <p>List of changes to clause 27:</p> |
| <ol> |
| <li> |
| In lib.basic.ios.members paragraph 13 (postcondition clause for |
| 'fill(cT)') change |
| |
| <blockquote><pre> fillch == fill() |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(fillch, fill()) |
| </pre></blockquote> |
| |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 7 (effects clause for |
| 'get(cT,streamsize,cT)'), third bullet, change |
| |
| <blockquote><pre> c == delim for the next available input character c |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(c, delim) for the next available input character c |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 12 (effects clause for |
| 'get(basic_streambuf<cT,Tr>&,cT)'), third bullet, change |
| |
| <blockquote><pre> c == delim for the next available input character c |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(c, delim) for the next available input character c |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 17 (effects clause for |
| 'getline(cT,streamsize,cT)'), second bullet, change |
| |
| <blockquote><pre> c == delim for the next available input character c |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(c, delim) for the next available input character c |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 24 (effects clause for |
| 'ignore(int,int_type)'), second bullet, change |
| |
| <blockquote><pre> c == delim for the next available input character c |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq_int_type(c, delim) for the next available input |
| character c |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.unformatted paragraph 25 (notes clause for |
| 'ignore(int,int_type)'), second bullet, change |
| |
| <blockquote><pre> The last condition will never occur if delim == traits::eof() |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> The last condition will never occur if |
| traits::eq_int_type(delim, traits::eof()). |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.istream.sentry paragraph 6 (example implementation for the |
| sentry constructor) change |
| |
| <blockquote><pre> while ((c = is.rdbuf()->snextc()) != traits::eof()) { |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> while (!traits::eq_int_type(c = is.rdbuf()->snextc(), traits::eof())) { |
| </pre></blockquote> |
| |
| </li> |
| </ol> |
| |
| <p>List of changes to Chapter 21:</p> |
| |
| <ol> |
| <li> |
| In lib.string::find paragraph 1 (effects clause for find()), |
| second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.string::rfind paragraph 1 (effects clause for rfind()), |
| second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.first.of paragraph 1 (effects clause for |
| find_first_of()), second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.last.of paragraph 1 (effects clause for |
| find_last_of()), second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| |
| </li> |
| <li> |
| In lib.string::find.first.not.of paragraph 1 (effects clause for |
| find_first_not_of()), second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| </li> |
| |
| <li> |
| In lib.string::find.last.not.of paragraph 1 (effects clause for |
| find_last_not_of()), second bullet, change |
| |
| <blockquote><pre> at(xpos+I) == str.at(I) for all elements ... |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(at(xpos+I), str.at(I)) for all elements ... |
| </pre></blockquote> |
| </li> |
| |
| <li> |
| In lib.string.ios paragraph 5 (effects clause for getline()), |
| second bullet, change |
| |
| <blockquote><pre> c == delim for the next available input character c |
| </pre></blockquote> |
| |
| to |
| |
| <blockquote><pre> traits::eq(c, delim) for the next available input character c |
| </pre></blockquote> |
| </li> |
| |
| </ol> |
| |
| <p>Notes:</p> |
| <ul> |
| <li> |
| Fixing this issue highlights another sloppyness in |
| lib.istream.unformatted paragraph 24: this clause mentions a "character" |
| which is then compared to an 'int_type' (see item 5. in the list |
| below). It is not clear whether this requires explicit words and |
| if so what these words are supposed to be. A similar issue exists, |
| BTW, for operator*() of istreambuf_iterator which returns the result |
| of sgetc() as a character type (see lib.istreambuf.iterator::op* |
| paragraph 1), and for operator++() of istreambuf_iterator which |
| passes the result of sbumpc() to a constructor taking a char_type |
| (see lib.istreambuf.iterator::operator++ paragraph 3). Similarily, the |
| assignment operator ostreambuf_iterator passes a char_type to a function |
| taking an int_type (see lib.ostreambuf.iter.ops paragraph 1). |
| </li> |
| <li> |
| It is inconsistent to use comparisons using the traits functions in |
| Chapter 27 while not using them in Chapter 21, especially as some |
| of the inconsistent uses actually involve streams (eg. getline() on |
| streams). To avoid leaving this issue open still longer due to this |
| inconsistency (it is open since 1998), a list of changes to Chapter |
| 21 is below. |
| </li> |
| <li> |
| In Chapter 24 there are several places with statements like "the end |
| of stream is reached (streambuf_type::sgetc() returns traits::eof())" |
| (lib.istreambuf.iterator paragraph 1, lib.ostreambuf.iter.ops |
| paragraph 5). It is unclear whether these should be clarified to use |
| traits::eq_int_type() for detecting traits::eof(). |
| </li> |
| </ul> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="46"></a>46. Minor Annex D errors</h3> |
| <p><b>Section:</b> D.7 [depr.str.strstreams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Brendan Kehoe <b>Date:</b> 1998-06-01</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p><p>See lib-6522 and edit-814.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change D.7.1 [depr.strstreambuf] (since streambuf is a typedef of |
| basic_streambuf<char>) from:</p> |
| |
| <pre> virtual streambuf<char>* setbuf(char* s, streamsize n);</pre> |
| |
| <p>to:</p> |
| |
| <pre> virtual streambuf* setbuf(char* s, streamsize n);</pre> |
| |
| <p>In D.7.4 [depr.strstream] insert the semicolon now missing after |
| int_type:</p> |
| |
| <pre> namespace std { |
| class strstream |
| : public basic_iostream<char> { |
| public: |
| // Types |
| typedef char char_type; |
| typedef typename char_traits<char>::int_type int_type |
| typedef typename char_traits<char>::pos_type pos_type;</pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="47"></a>47. Imbue() and getloc() Returns clauses swapped</h3> |
| <p><b>Section:</b> 27.4.2.3 [ios.base.locales] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base.locales">issues</a> in [ios.base.locales].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 27.4.2.3 specifies how imbue() and getloc() work. That |
| section has two RETURNS clauses, and they make no sense as |
| stated. They make perfect sense, though, if you swap them. Am I |
| correct in thinking that paragraphs 2 and 4 just got mixed up by |
| accident?</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2.3 [ios.base.locales] swap paragraphs 2 and 4.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="48"></a>48. Use of non-existent exception constructor</h3> |
| <p><b>Section:</b> 27.4.2.1.1 [ios::failure] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios::failure">issues</a> in [ios::failure].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.4.2.1.1, paragraph 2, says that class failure initializes the |
| base class, exception, with exception(msg). Class exception (see |
| 18.6.1) has no such constructor.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.4.2.1.1 [ios::failure], paragraph 2, with</p> |
| |
| <blockquote> |
| <p>EFFECTS: Constructs an object of class <tt>failure</tt>.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="49"></a>49. Underspecification of ios_base::sync_with_stdio</h3> |
| <p><b>Section:</b> 27.4.2.4 [ios.members.static] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-21</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Two problems</p> |
| |
| <p>(1) 27.4.2.4 doesn't say what ios_base::sync_with_stdio(f) |
| returns. Does it return f, or does it return the previous |
| synchronization state? My guess is the latter, but the standard |
| doesn't say so.</p> |
| |
| <p>(2) 27.4.2.4 doesn't say what it means for streams to be |
| synchronized with stdio. Again, of course, I can make some |
| guesses. (And I'm unhappy about the performance implications of those |
| guesses, but that's another matter.)</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the following sentence in 27.4.2.4 [ios.members.static] |
| returns clause from:</p> |
| |
| <blockquote> |
| <p><tt>true</tt> if the standard iostream objects (27.3) are |
| synchronized and otherwise returns <tt>false</tt>.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p><tt>true</tt> if the previous state of the standard iostream |
| objects (27.3) was synchronized and otherwise returns |
| <tt>false</tt>.</p> |
| </blockquote> |
| |
| <p>Add the following immediately after 27.4.2.4 [ios.members.static], |
| paragraph 2:</p> |
| |
| <blockquote> |
| <p>When a standard iostream object str is <i>synchronized</i> with a |
| standard stdio stream f, the effect of inserting a character c by</p> |
| <pre> fputc(f, c); |
| </pre> |
| |
| <p>is the same as the effect of</p> |
| <pre> str.rdbuf()->sputc(c); |
| </pre> |
| |
| <p>for any sequence of characters; the effect of extracting a |
| character c by</p> |
| <pre> c = fgetc(f); |
| </pre> |
| |
| <p>is the same as the effect of:</p> |
| <pre> c = str.rdbuf()->sbumpc(c); |
| </pre> |
| |
| <p>for any sequences of characters; and the effect of pushing |
| back a character c by</p> |
| <pre> ungetc(c, f); |
| </pre> |
| |
| <p>is the same as the effect of</p> |
| <pre> str.rdbuf()->sputbackc(c); |
| </pre> |
| |
| <p>for any sequence of characters. [<i>Footnote</i>: This implies |
| that operations on a standard iostream object can be mixed arbitrarily |
| with operations on the corresponding stdio stream. In practical |
| terms, synchronization usually means that a standard iostream object |
| and a standard stdio object share a buffer. <i>--End Footnote</i>]</p> |
| </blockquote> |
| |
| <p><i>[pre-Copenhagen: PJP and Matt contributed the definition |
| of "synchronization"]</i></p> |
| |
| |
| <p><i>[post-Copenhagen: proposed resolution was revised slightly: |
| text was added in the non-normative footnote to say that operations |
| on the two streams can be mixed arbitrarily.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="50"></a>50. Copy constructor and assignment operator of ios_base</h3> |
| <p><b>Section:</b> 27.4.2 [ios.base] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base">issues</a> in [ios.base].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>As written, ios_base has a copy constructor and an assignment |
| operator. (Nothing in the standard says it doesn't have one, and all |
| classes have copy constructors and assignment operators unless you |
| take specific steps to avoid them.) However, nothing in 27.4.2 says |
| what the copy constructor and assignment operator do. </p> |
| |
| <p>My guess is that this was an oversight, that ios_base is, like |
| basic_ios, not supposed to have a copy constructor or an assignment |
| operator.</p> |
| |
| <p> |
| Jerry Schwarz comments: Yes, its an oversight, but in the opposite |
| sense to what you're suggesting. At one point there was a definite |
| intention that you could copy ios_base. It's an easy way to save the |
| entire state of a stream for future use. As you note, to carry out |
| that intention would have required a explicit description of the |
| semantics (e.g. what happens to the iarray and parray stuff). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2 [ios.base], class ios_base, specify the copy |
| constructor and operator= members as being private.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes the difficulty of specifying correct semantics |
| outweighs any benefit of allowing ios_base objects to be copyable.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="51"></a>51. Requirement to not invalidate iterators missing</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> David Vandevoorde <b>Date:</b> 1998-06-23</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The std::sort algorithm can in general only sort a given sequence |
| by moving around values. The list<>::sort() member on the other |
| hand could move around values or just update internal pointers. Either |
| method can leave iterators into the list<> dereferencable, but |
| they would point to different things. </p> |
| |
| <p>Does the FDIS mandate anywhere which method should be used for |
| list<>::sort()?</p> |
| |
| <p>Matt Austern comments:</p> |
| |
| <p>I think you've found an omission in the standard. </p> |
| |
| <p>The library working group discussed this point, and there was |
| supposed to be a general requirement saying that list, set, map, |
| multiset, and multimap may not invalidate iterators, or change the |
| values that iterators point to, except when an operation does it |
| explicitly. So, for example, insert() doesn't invalidate any iterators |
| and erase() and remove() only invalidate iterators pointing to the |
| elements that are being erased. </p> |
| |
| <p>I looked for that general requirement in the FDIS, and, while I |
| found a limited form of it for the sorted associative containers, I |
| didn't find it for list. It looks like it just got omitted. </p> |
| |
| <p>The intention, though, is that list<>::sort does not |
| invalidate any iterators and does not change the values that any |
| iterator points to. There would be no reason to have the member |
| function otherwise.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph at the end of 23.1:</p> |
| |
| <blockquote> |
| <p>Unless otherwise specified (either explicitly or by defining a function in terms of |
| other functions), invoking a container member function or passing a container as an |
| argument to a library function shall not invalidate iterators to, or change the values of, |
| objects within that container. </p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This was US issue CD2-23-011; it was accepted in London but the |
| change was not made due to an editing oversight. The wording in the |
| proposed resolution below is somewhat updated from CD2-23-011, |
| particularly the addition of the phrase "or change the values |
| of"</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="52"></a>52. Small I/O problems</h3> |
| <p><b>Section:</b> 27.4.3.2 [fpos.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>First, 27.4.4.1 [basic.ios.cons], table 89. This is pretty obvious: |
| it should be titled "basic_ios<>() effects", not |
| "ios_base() effects". </p> |
| |
| <p>[The second item is a duplicate; see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#6">6</a> for |
| resolution.]</p> |
| |
| <p>Second, 27.4.3.2 [fpos.operations] table 88 . There are a couple |
| different things wrong with it, some of which I've already discussed |
| with Jerry, but the most obvious mechanical sort of error is that it |
| uses expressions like P(i) and p(i), without ever defining what sort |
| of thing "i" is. |
| </p> |
| |
| <p>(The other problem is that it requires support for streampos |
| arithmetic. This is impossible on some systems, i.e. ones where file |
| position is a complicated structure rather than just a number. Jerry |
| tells me that the intention was to require syntactic support for |
| streampos arithmetic, but that it wasn't actually supposed to do |
| anything meaningful except on platforms, like Unix, where genuine |
| arithmetic is possible.) </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.4.4.1 [basic.ios.cons] table 89 title from |
| "ios_base() effects" to "basic_ios<>() |
| effects". </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="53"></a>53. Basic_ios destructor unspecified</h3> |
| <p><b>Section:</b> 27.4.4.1 [basic.ios.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.ios.cons">issues</a> in [basic.ios.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>There's nothing in 27.4.4 saying what basic_ios's destructor does. |
| The important question is whether basic_ios::~basic_ios() destroys |
| rdbuf().</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add after 27.4.4.1 [basic.ios.cons] paragraph 2:</p> |
| |
| <blockquote> |
| <p><tt>virtual ~basic_ios();</tt></p> |
| <p><b>Notes</b>: The destructor does not destroy <tt>rdbuf()</tt>.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG reviewed the additional question of whether or not |
| <tt>rdbuf(0)</tt> may set <tt>badbit</tt>. The answer is |
| clearly yes; it may be set via <tt>clear()</tt>. See 27.4.4.2 [basic.ios.members], paragraph 6. This issue was reviewed at length |
| by the LWG, which removed from the original proposed resolution a |
| footnote which incorrectly said "<tt>rdbuf(0)</tt> does not set |
| <tt>badbit</tt>".</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="54"></a>54. Basic_streambuf's destructor</h3> |
| <p><b>Section:</b> 27.5.2.1 [streambuf.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#streambuf.cons">issues</a> in [streambuf.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The class synopsis for basic_streambuf shows a (virtual) |
| destructor, but the standard doesn't say what that destructor does. My |
| assumption is that it does nothing, but the standard should say so |
| explicitly. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add after 27.5.2.1 [streambuf.cons] paragraph 2:</p> |
| |
| <blockquote> |
| <p><tt>virtual ~basic_streambuf();</tt></p> |
| <p><b>Effects</b>: None.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="55"></a>55. Invalid stream position is undefined</h3> |
| <p><b>Section:</b> 27 [input.output] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.output">issues</a> in [input.output].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Several member functions in clause 27 are defined in certain |
| circumstances to return an "invalid stream position", a term |
| that is defined nowhere in the standard. Two places (27.5.2.4.2, |
| paragraph 4, and 27.8.1.4, paragraph 15) contain a cross-reference to |
| a definition in _lib.iostreams.definitions_, a nonexistent |
| section. </p> |
| |
| <p>I suspect that the invalid stream position is just supposed to be |
| pos_type(-1). Probably best to say explicitly in (for example) |
| 27.5.2.4.2 that the return value is pos_type(-1), rather than to use |
| the term "invalid stream position", define that term |
| somewhere, and then put in a cross-reference. </p> |
| |
| <p>The phrase "invalid stream position" appears ten times in |
| the C++ Standard. In seven places it refers to a return value, and it |
| should be changed. In three places it refers to an argument, and it |
| should not be changed. Here are the three places where "invalid |
| stream position" should not be changed:</p> |
| |
| <blockquote> |
| <p>27.7.1.4 [stringbuf.virtuals], paragraph 14<br> |
| 27.8.1.5 [filebuf.virtuals], paragraph 14<br> |
| D.7.1.3 [depr.strstreambuf.virtuals], paragraph 17 |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.5.2.4.2 [streambuf.virt.buffer], paragraph 4, change "Returns an |
| object of class pos_type that stores an invalid stream position |
| (_lib.iostreams.definitions_)" to "Returns |
| <tt>pos_type(off_type(-1))</tt>". |
| </p> |
| |
| <p>In 27.5.2.4.2 [streambuf.virt.buffer], paragraph 6, change "Returns |
| an object of class pos_type that stores an invalid stream |
| position" to "Returns <tt>pos_type(off_type(-1))</tt>".</p> |
| |
| <p>In 27.7.1.4 [stringbuf.virtuals], paragraph 13, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>". </p> |
| |
| <p>In 27.8.1.5 [filebuf.virtuals], paragraph 13, change "returns an |
| invalid stream position (27.4.3)" to "returns |
| <tt>pos_type(off_type(-1))</tt>" </p> |
| |
| <p>In 27.8.1.5 [filebuf.virtuals], paragraph 15, change "Otherwise |
| returns an invalid stream position (_lib.iostreams.definitions_)" |
| to "Otherwise returns <tt>pos_type(off_type(-1))</tt>" |
| </p> |
| |
| <p>In D.7.1.3 [depr.strstreambuf.virtuals], paragraph 15, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>" </p> |
| |
| <p>In D.7.1.3 [depr.strstreambuf.virtuals], paragraph 18, change "the object |
| stores an invalid stream position" to "the return value is |
| <tt>pos_type(off_type(-1))</tt>"</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="56"></a>56. Showmanyc's return type</h3> |
| <p><b>Section:</b> 27.5.2 [streambuf] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-06-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#streambuf">issues</a> in [streambuf].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The class summary for basic_streambuf<>, in 27.5.2, says that |
| showmanyc has return type int. However, 27.5.2.4.3 says that its |
| return type is streamsize. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change <tt>showmanyc</tt>'s return type in the |
| 27.5.2 [streambuf] class summary to <tt>streamsize</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="57"></a>57. Mistake in char_traits</h3> |
| <p><b>Section:</b> 21.1.3.4 [char.traits.specializations.wchar.t] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-07-01</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>21.1.3.2, paragraph 3, says "The types streampos and |
| wstreampos may be different if the implementation supports no shift |
| encoding in narrow-oriented iostreams but supports one or more shift |
| encodings in wide-oriented streams". </p> |
| |
| <p>That's wrong: the two are the same type. The <iosfwd> summary |
| in 27.2 says that streampos and wstreampos are, respectively, synonyms |
| for fpos<char_traits<char>::state_type> and |
| fpos<char_traits<wchar_t>::state_type>, and, flipping back |
| to clause 21, we see in 21.1.3.1 and 21.1.3.2 that |
| char_traits<char>::state_type and |
| char_traits<wchar_t>::state_type must both be mbstate_t. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the sentence in 21.1.3.4 [char.traits.specializations.wchar.t] paragraph 3 which |
| begins "The types streampos and wstreampos may be |
| different..." . </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="59"></a>59. Ambiguity in specification of gbump</h3> |
| <p><b>Section:</b> 27.5.2.3.2 [streambuf.get.area] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-07-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.5.2.3.1 says that basic_streambuf::gbump() "Advances the |
| next pointer for the input sequence by n." </p> |
| |
| <p>The straightforward interpretation is that it is just gptr() += |
| n. An alternative interpretation, though, is that it behaves as if it |
| calls sbumpc n times. (The issue, of course, is whether it might ever |
| call underflow.) There is a similar ambiguity in the case of |
| pbump. </p> |
| |
| <p>(The "classic" AT&T implementation used the |
| former interpretation.)</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.3.2 [streambuf.get.area] paragraph 4 gbump effects from:</p> |
| |
| <blockquote> |
| <p>Effects: Advances the next pointer for the input sequence by n.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Adds <tt>n</tt> to the next pointer for the input sequence.</p> |
| </blockquote> |
| |
| <p>Make the same change to 27.5.2.3.3 [streambuf.put.area] paragraph 4 pbump |
| effects.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="60"></a>60. What is a formatted input function?</h3> |
| <p><b>Section:</b> 27.6.1.2.1 [istream.formatted.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.formatted.reqmts">issues</a> in [istream.formatted.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#162">162</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#163">163</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#166">166</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 1 of 27.6.1.2.1 contains general requirements for all |
| formatted input functions. Some of the functions defined in section |
| 27.6.1.2 explicitly say that those requirements apply ("Behaves |
| like a formatted input member (as described in 27.6.1.2.1)"), but |
| others don't. The question: is 27.6.1.2.1 supposed to apply to |
| everything in 27.6.1.2, or only to those member functions that |
| explicitly say "behaves like a formatted input member"? Or |
| to put it differently: are we to assume that everything that appears |
| in a section called "Formatted input functions" really is a |
| formatted input function? I assume that 27.6.1.2.1 is intended to |
| apply to the arithmetic extractors (27.6.1.2.2), but I assume that it |
| is not intended to apply to extractors like </p> |
| |
| <pre> basic_istream& operator>>(basic_istream& (*pf)(basic_istream&));</pre> |
| |
| <p>and </p> |
| |
| <pre> basic_istream& operator>>(basic_streammbuf*);</pre> |
| |
| <p>There is a similar ambiguity for unformatted input, formatted output, and unformatted |
| output. </p> |
| |
| <p>Comments from Judy Ward: It seems like the problem is that the |
| basic_istream and basic_ostream operator <<()'s that are used |
| for the manipulators and streambuf* are in the wrong section and |
| should have their own separate section or be modified to make it clear |
| that the "Common requirements" listed in section 27.6.1.2.1 |
| (for basic_istream) and section 27.6.2.5.1 (for basic_ostream) do not |
| apply to them. </p> |
| |
| <p>Additional comments from Dietmar Kühl: It appears to be somewhat |
| nonsensical to consider the functions defined in 27.6.1.2.3 |
| [istream::extractors] paragraphs 1 to 5 to be "Formatted input |
| function" but since these functions are defined in a section |
| labeled "Formatted input functions" it is unclear to me |
| whether these operators are considered formatted input functions which |
| have to conform to the "common requirements" from 27.6.1.2.1 |
| [istream.formatted.reqmts]: If this is the case, all manipulators, not |
| just <tt>ws</tt>, would skip whitespace unless <tt>noskipws</tt> is |
| set (... but setting <tt>noskipws</tt> using the manipulator syntax |
| would also skip whitespace :-)</p> <p>It is not clear which functions |
| are to be considered unformatted input functions. As written, it seems |
| that all functions in 27.6.1.3 [istream.unformatted] are unformatted input |
| functions. However, it does not really make much sense to construct a |
| sentry object for <tt>gcount()</tt>, <tt>sync()</tt>, ... Also it is |
| unclear what happens to the <tt>gcount()</tt> if |
| eg. <tt>gcount()</tt>, <tt>putback()</tt>, <tt>unget()</tt>, or |
| <tt>sync()</tt> is called: These functions don't extract characters, |
| some of them even "unextract" a character. Should this still |
| be reflected in <tt>gcount()</tt>? Of course, it could be read as if |
| after a call to <tt>gcount()</tt> <tt>gcount()</tt> return <tt>0</tt> |
| (the last unformatted input function, <tt>gcount()</tt>, didn't |
| extract any character) and after a call to <tt>putback()</tt> |
| <tt>gcount()</tt> returns <tt>-1</tt> (the last unformatted input |
| function <tt>putback()</tt> did "extract" back into the |
| stream). Correspondingly for <tt>unget()</tt>. Is this what is |
| intended? If so, this should be clarified. Otherwise, a corresponding |
| clarification should be used.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.2.2 [lib.istream.formatted.arithmetic], paragraph 1. |
| Change the beginning of the second sentence from "The conversion |
| occurs" to "These extractors behave as formatted input functions (as |
| described in 27.6.1.2.1). After a sentry object is constructed, |
| the conversion occurs" |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], before paragraph 1. |
| Add an effects clause. "Effects: None. This extractor does |
| not behave as a formatted input function (as described in |
| 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 2. Change the |
| effects clause to "Effects: Calls pf(*this). This extractor does not |
| behave as a formatted input function (as described in 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 4. Change the |
| effects clause to "Effects: Calls pf(*this). This extractor does not |
| behave as a formatted input function (as described in 27.6.1.2.1). |
| </p> |
| |
| <p> |
| In 27.6.1.2.3, [lib.istream::extractors], paragraph 12. Change the |
| first two sentences from "If sb is null, calls setstate(failbit), |
| which may throw ios_base::failure (27.4.4.3). Extracts characters |
| from *this..." to "Behaves as a formatted input function (as described |
| in 27.6.1.2.1). If sb is null, calls setstate(failbit), which may |
| throw ios_base::failure (27.4.4.3). After a sentry object is |
| constructed, extracts characters from *this...". |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 2. Add an |
| effects clause. "Effects: none. This member function does not behave |
| as an unformatted input function (as described in 27.6.1.3, paragraph 1)." |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 3. Change the |
| beginning of the first sentence of the effects clause from "Extracts a |
| character" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts a |
| character" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 5. Change the |
| beginning of the first sentence of the effects clause from "Extracts a |
| character" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts a |
| character" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 7. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 10, because it refers to paragraph 7.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 12. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 15.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 17. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| [No change needed in paragraph 23.] |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 24. Change the |
| beginning of the first sentence of the effects clause from "Extracts |
| characters" to "Behaves as an unformatted input function (as described |
| in 27.6.1.3, paragraph 1). After constructing a sentry object, extracts |
| characters" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 27. Add an |
| Effects clause: "Effects: Behaves as an unformatted input function (as |
| described in 27.6.1.3, paragraph 1). After constructing a sentry |
| object, reads but does not extract the current input character." |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 28. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 30. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 32. Change the |
| first sentence of the Effects clause from "If !good() calls..." to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() |
| calls..." Add a new sentence to the end of the Effects clause: |
| "[Note: this function extracts no characters, so the value returned |
| by the next call to gcount() is 0.]" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 34. Change the |
| first sentence of the Effects clause from "If !good() calls" to |
| "Behaves as an unformatted input function (as described in 27.6.1.3, |
| paragraph 1). After constructing a sentry object, if !good() calls". |
| Add a new sentence to the end of the Effects clause: "[Note: this |
| function extracts no characters, so the value returned by the next |
| call to gcount() is 0.]" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 36. Change the |
| first sentence of the Effects clause from "If !rdbuf() is" to "Behaves |
| as an unformatted input function (as described in 27.6.1.3, paragraph |
| 1), except that it does not count the number of characters extracted |
| and does not affect the value returned by subsequent calls to |
| gcount(). After constructing a sentry object, if rdbuf() is" |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], before paragraph 37. Add an |
| Effects clause: "Effects: Behaves as an unformatted input function (as |
| described in 27.6.1.3, paragraph 1), except that it does not count the |
| number of characters extracted and does not affect the value returned |
| by subsequent calls to gcount()." Change the first sentence of |
| paragraph 37 from "if fail()" to "after constructing a sentry object, |
| if fail()". |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 38. Change the |
| first sentence of the Effects clause from "If fail()" to "Behaves |
| as an unformatted input function (as described in 27.6.1.3, paragraph |
| 1), except that it does not count the number of characters extracted |
| and does not affect the value returned by subsequent calls to |
| gcount(). After constructing a sentry object, if fail() |
| </p> |
| |
| <p> |
| In 27.6.1.3, [lib.istream.unformatted], paragraph 40. Change the |
| first sentence of the Effects clause from "If fail()" to "Behaves |
| as an unformatted input function (as described in 27.6.1.3, paragraph |
| 1), except that it does not count the number of characters extracted |
| and does not affect the value returned by subsequent calls to |
| gcount(). After constructing a sentry object, if fail() |
| </p> |
| |
| <p> |
| In 27.6.2.5.2 [lib.ostream.inserters.arithmetic], paragraph 1. Change |
| the beginning of the third sentence from "The formatting conversion" |
| to "These extractors behave as formatted output functions (as |
| described in 27.6.2.5.1). After the sentry object is constructed, the |
| conversion occurs". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], before paragraph 1. Add an |
| effects clause: "Effects: None. Does not behave as a formatted output |
| function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 2. Change the |
| effects clause to "Effects: calls pf(*this). This extractor does not |
| behave as a formatted output function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 4. Change the |
| effects clause to "Effects: calls pf(*this). This extractor does not |
| behave as a formatted output function (as described in 27.6.2.5.1).". |
| </p> |
| |
| <p> |
| In 27.6.2.5.3 [lib.ostream.inserters], paragraph 6. Change the first |
| sentence from "If sb" to "Behaves as a formatted output function (as |
| described in 27.6.2.5.1). After the sentry object is constructed, if |
| sb". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 2. Change the first |
| sentence from "Inserts the character" to "Behaves as an unformatted |
| output function (as described in 27.6.2.6, paragraph 1). After |
| constructing a sentry object, inserts the character". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 5. Change the first |
| sentence from "Obtains characters" to "Behaves as an unformatted |
| output function (as described in 27.6.2.6, paragraph 1). After |
| constructing a sentry object, obtains characters". |
| </p> |
| |
| <p> |
| In 27.6.2.6 [lib.ostream.unformatted], paragraph 7. Add a new |
| sentence at the end of the paragraph: "Does not behave as an |
| unformatted output function (as described in 27.6.2.6, paragraph 1)." |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>See J16/99-0043==WG21/N1219, Proposed Resolution to Library Issue 60, |
| by Judy Ward and Matt Austern. This proposed resolution is section |
| VI of that paper.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="61"></a>61. Ambiguity in iostreams exception policy</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The introduction to the section on unformatted input (27.6.1.3) |
| says that every unformatted input function catches all exceptions that |
| were thrown during input, sets badbit, and then conditionally rethrows |
| the exception. That seems clear enough. Several of the specific |
| functions, however, such as get() and read(), are documented in some |
| circumstances as setting eofbit and/or failbit. (The standard notes, |
| correctly, that setting eofbit or failbit can sometimes result in an |
| exception being thrown.) The question: if one of these functions |
| throws an exception triggered by setting failbit, is this an exception |
| "thrown during input" and hence covered by 27.6.1.3, or does |
| 27.6.1.3 only refer to a limited class of exceptions? Just to make |
| this concrete, suppose you have the following snippet. </p> |
| |
| <pre> |
| char buffer[N]; |
| istream is; |
| ... |
| is.exceptions(istream::failbit); // Throw on failbit but not on badbit. |
| is.read(buffer, N);</pre> |
| |
| <p>Now suppose we reach EOF before we've read N characters. What |
| iostate bits can we expect to be set, and what exception (if any) will |
| be thrown? </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.3, paragraph 1, after the sentence that begins |
| "If an exception is thrown...", add the following |
| parenthetical comment: "(Exceptions thrown from |
| <tt>basic_ios<>::clear()</tt> are not caught or rethrown.)" |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG looked to two alternative wordings, and choose the proposed |
| resolution as better standardese.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="62"></a>62. <tt>Sync</tt>'s return value</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The Effects clause for sync() (27.6.1.3, paragraph 36) says that it |
| "calls rdbuf()->pubsync() and, if that function returns -1 |
| ... returns traits::eof()." </p> |
| |
| <p>That looks suspicious, because traits::eof() is of type |
| traits::int_type while the return type of sync() is int. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.3 [istream.unformatted], paragraph 36, change "returns |
| <tt>traits::eof()</tt>" to "returns <tt>-1</tt>". |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="63"></a>63. Exception-handling policy for unformatted output</h3> |
| <p><b>Section:</b> 27.6.2.7 [ostream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-11</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.unformatted">issues</a> in [ostream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Clause 27 details an exception-handling policy for formatted input, |
| unformatted input, and formatted output. It says nothing for |
| unformatted output (27.6.2.6). 27.6.2.6 should either include the same |
| kind of exception-handling policy as in the other three places, or |
| else it should have a footnote saying that the omission is |
| deliberate. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.2.6, paragraph 1, replace the last sentence ("In any |
| case, the unformatted output function ends by destroying the sentry |
| object, then returning the value specified for the formatted output |
| function.") with the following text: |
| </p> |
| <blockquote><p> |
| If an exception is thrown during output, then <tt>ios::badbit</tt> is |
| turned on [Footnote: without causing an <tt>ios::failure</tt> to be |
| thrown.] in <tt>*this</tt>'s error state. If <tt>(exceptions() & |
| badbit) != 0</tt> then the exception is rethrown. In any case, the |
| unformatted output function ends by destroying the sentry object, |
| then, if no exception was thrown, returning the value specified for |
| the formatted output function. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This exception-handling policy is consistent with that of formatted |
| input, unformatted input, and formatted output. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="64"></a>64. Exception handling in <tt>basic_istream::operator>>(basic_streambuf*)</tt></h3> |
| <p><b>Section:</b> 27.6.1.2.3 [istream::extractors] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-11</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::extractors">issues</a> in [istream::extractors].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.6.1.2.3, paragraph 13, is ambiguous. It can be interpreted two |
| different ways, depending on whether the second sentence is read as an |
| elaboration of the first. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.6.1.2.3 [istream::extractors], paragraph 13, which begins |
| "If the function inserts no characters ..." with:</p> |
| |
| <blockquote> |
| <p>If the function inserts no characters, it calls |
| <tt>setstate(failbit)</tt>, which may throw |
| <tt>ios_base::failure</tt> (27.4.4.3). If it inserted no characters |
| because it caught an exception thrown while extracting characters |
| from <tt>sb</tt> and <tt>failbit</tt> is on in <tt>exceptions()</tt> |
| (27.4.4.3), then the caught exception is rethrown. </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="66"></a>66. Strstreambuf::setbuf</h3> |
| <p><b>Section:</b> D.7.1.3 [depr.strstreambuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-08-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.strstreambuf.virtuals">issues</a> in [depr.strstreambuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>D.7.1.3, paragraph 19, says that strstreambuf::setbuf |
| "Performs an operation that is defined separately for each class |
| derived from strstreambuf". This is obviously an incorrect |
| cut-and-paste from basic_streambuf. There are no classes derived from |
| strstreambuf. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>D.7.1.3 [depr.strstreambuf.virtuals], paragraph 19, replace the setbuf effects |
| clause which currently says "Performs an operation that is |
| defined separately for each class derived from strstreambuf" |
| with:</p> |
| |
| <blockquote> |
| <p><b>Effects</b>: implementation defined, except that |
| <tt>setbuf(0,0)</tt> has no effect.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="68"></a>68. Extractors for char* should store null at end</h3> |
| <p><b>Section:</b> 27.6.1.2.3 [istream::extractors] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 1998-07-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::extractors">issues</a> in [istream::extractors].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Extractors for char* (27.6.1.2.3) do not store a null character |
| after the extracted character sequence whereas the unformatted |
| functions like get() do. Why is this?</p> |
| |
| <p>Comment from Jerry Schwarz: There is apparently an editing |
| glitch. You'll notice that the last item of the list of what stops |
| extraction doesn't make any sense. It was supposed to be the line that |
| said a null is stored.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>27.6.1.2.3 [istream::extractors], paragraph 7, change the last list |
| item from:</p> |
| |
| <blockquote><p> |
| A null byte (<tt>charT()</tt>) in the next position, which may be |
| the first position if no characters were extracted. |
| </p></blockquote> |
| |
| <p>to become a new paragraph which reads:</p> |
| |
| <blockquote><p> |
| Operator>> then stores a null byte (<tt>charT()</tt>) in the |
| next position, which may be the first position if no characters were |
| extracted. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="69"></a>69. Must elements of a vector be contiguous?</h3> |
| <p><b>Section:</b> 23.2.6 [vector] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1998-07-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector">issues</a> in [vector].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The issue is this: Must the elements of a vector be in contiguous memory?</p> |
| |
| <p>(Please note that this is entirely separate from the question of |
| whether a vector iterator is required to be a pointer; the answer to |
| that question is clearly "no," as it would rule out |
| debugging implementations)</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of 23.2.6 [vector], |
| paragraph 1. </p> |
| |
| <blockquote> |
| <p>The elements of a vector are stored contiguously, meaning that if |
| v is a <tt>vector<T, Allocator></tt> where T is some type |
| other than <tt>bool</tt>, then it obeys the identity <tt>&v[n] |
| == &v[0] + n</tt> for all <tt>0 <= n < v.size()</tt>.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG feels that as a practical matter the answer is clearly |
| "yes". There was considerable discussion as to the best way |
| to express the concept of "contiguous", which is not |
| directly defined in the standard. Discussion included:</p> |
| |
| <ul> |
| <li>An operational definition similar to the above proposed resolution is |
| already used for valarray (26.5.2.3 [valarray.access]).</li> |
| <li>There is no need to explicitly consider a user-defined operator& |
| because elements must be copyconstructible (23.1 [container.requirements] para 3) |
| and copyconstructible (20.1.1 [utility.arg.requirements]) specifies |
| requirements for operator&.</li> |
| <li>There is no issue of one-past-the-end because of language rules.</li> |
| </ul> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="70"></a>70. Uncaught_exception() missing throw() specification</h3> |
| <p><b>Section:</b> 18.7 [support.exception], 18.7.4 [uncaught] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 1998-08-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#support.exception">issues</a> in [support.exception].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In article 3E04@pratique.fr, Valentin Bonnard writes: </p> |
| |
| <p>uncaught_exception() doesn't have a throw specification.</p> |
| |
| <p>It is intentional ? Does it means that one should be prepared to |
| handle exceptions thrown from uncaught_exception() ?</p> |
| |
| <p>uncaught_exception() is called in exception handling contexts where |
| exception safety is very important.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 15.5.3 [except.uncaught], paragraph 1, 18.7 [support.exception], |
| and 18.7.4 [uncaught], add "throw()" to uncaught_exception().</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="71"></a>71. Do_get_monthname synopsis missing argument</h3> |
| <p><b>Section:</b> 22.2.5.1 [locale.time.get] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-08-13</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The locale facet member <tt>time_get<>::do_get_monthname</tt> |
| is described in 22.2.5.1.2 [locale.time.get.virtuals] with five arguments, |
| consistent with do_get_weekday and with its specified use by member |
| get_monthname. However, in the synopsis, it is specified instead with |
| four arguments. The missing argument is the "end" iterator |
| value.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.5.1 [locale.time.get], add an "end" argument to |
| the declaration of member do_monthname as follows:</p> |
| |
| <pre> virtual iter_type do_get_monthname(iter_type s, iter_type end, ios_base&, |
| ios_base::iostate& err, tm* t) const;</pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="74"></a>74. Garbled text for <tt>codecvt::do_max_length</tt></h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-09-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The text of <tt>codecvt::do_max_length</tt>'s "Returns" |
| clause (22.2.1.5.2, paragraph 11) is garbled. It has unbalanced |
| parentheses and a spurious <b>n</b>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 22.2.1.4.2 [locale.codecvt.virtuals] paragraph 11 with the |
| following:</p> |
| |
| <blockquote><p> |
| <b>Returns</b>: The maximum value that |
| <tt>do_length(state, from, from_end, 1)</tt> can return for any |
| valid range <tt>[from, from_end)</tt> and <tt>stateT</tt> value |
| <tt>state</tt>. The specialization <tt>codecvt<char, char, |
| mbstate_t>::do_max_length()</tt> returns 1. |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="75"></a>75. Contradiction in <tt>codecvt::length</tt>'s argument types</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt |
| Austern <b>Date:</b> 1998-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The class synopses for classes <tt>codecvt<></tt> (22.2.1.5) |
| and <tt>codecvt_byname<></tt> (22.2.1.6) say that the first |
| parameter of the member functions <tt>length</tt> and |
| <tt>do_length</tt> is of type <tt>const stateT&</tt>. The member |
| function descriptions, however (22.2.1.5.1, paragraph 6; 22.2.1.5.2, |
| paragraph 9) say that the type is <tt>stateT&</tt>. Either the |
| synopsis or the summary must be changed. </p> |
| |
| <p>If (as I believe) the member function descriptions are correct, |
| then we must also add text saying how <tt>do_length</tt> changes its |
| <tt>stateT</tt> argument. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.1.4 [locale.codecvt], and also in 22.2.1.5 [locale.codecvt.byname], |
| change the <tt>stateT</tt> argument type on both member |
| <tt>length()</tt> and member <tt>do_length()</tt> from </p> |
| |
| <blockquote> |
| <p><tt>const stateT&</tt></p> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <p><tt>stateT&</tt></p> |
| </blockquote> |
| |
| <p>In 22.2.1.4.2 [locale.codecvt.virtuals], add to the definition for member |
| <tt>do_length</tt> a paragraph:</p> |
| |
| <blockquote> |
| <p>Effects: The effect on the <tt>state</tt> argument is ``as if'' |
| it called <tt>do_in(state, from, from_end, from, to, to+max, |
| to)</tt> for <tt>to</tt> pointing to a buffer of at least |
| <tt>max</tt> elements.</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="76"></a>76. Can a <tt>codecvt</tt> facet always convert one internal character at a time?</h3> |
| <p><b>Section:</b> 22.2.1.4 [locale.codecvt] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-09-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt">issues</a> in [locale.codecvt].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>This issue concerns the requirements on classes derived from |
| <tt>codecvt</tt>, including user-defined classes. What are the |
| restrictions on the conversion from external characters |
| (e.g. <tt>char</tt>) to internal characters (e.g. <tt>wchar_t</tt>)? |
| Or, alternatively, what assumptions about <tt>codecvt</tt> facets can |
| the I/O library make? </p> |
| |
| <p>The question is whether it's possible to convert from internal |
| characters to external characters one internal character at a time, |
| and whether, given a valid sequence of external characters, it's |
| possible to pick off internal characters one at a time. Or, to put it |
| differently: given a sequence of external characters and the |
| corresponding sequence of internal characters, does a position in the |
| internal sequence correspond to some position in the external |
| sequence? </p> |
| |
| <p>To make this concrete, suppose that <tt>[first, last)</tt> is a |
| sequence of <i>M</i> external characters and that <tt>[ifirst, |
| ilast)</tt> is the corresponding sequence of <i>N</i> internal |
| characters, where <i>N > 1</i>. That is, <tt>my_encoding.in()</tt>, |
| applied to <tt>[first, last)</tt>, yields <tt>[ifirst, |
| ilast)</tt>. Now the question: does there necessarily exist a |
| subsequence of external characters, <tt>[first, last_1)</tt>, such |
| that the corresponding sequence of internal characters is the single |
| character <tt>*ifirst</tt>? |
| </p> |
| |
| <p>(What a "no" answer would mean is that |
| <tt>my_encoding</tt> translates sequences only as blocks. There's a |
| sequence of <i>M</i> external characters that maps to a sequence of |
| <i>N</i> internal characters, but that external sequence has no |
| subsequence that maps to <i>N-1</i> internal characters.) </p> |
| |
| <p>Some of the wording in the standard, such as the description of |
| <tt>codecvt::do_max_length</tt> (22.2.1.4.2 [locale.codecvt.virtuals], |
| paragraph 11) and <tt>basic_filebuf::underflow</tt> (27.8.1.5 [filebuf.virtuals], paragraph 3) suggests that it must always be |
| possible to pick off internal characters one at a time from a sequence |
| of external characters. However, this is never explicitly stated one |
| way or the other. </p> |
| |
| <p>This issue seems (and is) quite technical, but it is important if |
| we expect users to provide their own encoding facets. This is an area |
| where the standard library calls user-supplied code, so a well-defined |
| set of requirements for the user-supplied code is crucial. Users must |
| be aware of the assumptions that the library makes. This issue affects |
| positioning operations on <tt>basic_filebuf</tt>, unbuffered input, |
| and several of <tt>codecvt</tt>'s member functions. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text as a new paragraph, following 22.2.1.4.2 [locale.codecvt.virtuals] paragraph 2:</p> |
| |
| <blockquote> |
| <p>A <tt>codecvt</tt> facet that is used by <tt>basic_filebuf</tt> |
| (27.8 [file.streams]) must have the property that if</p> |
| <pre> do_out(state, from, from_end, from_next, to, to_lim, to_next) |
| </pre> |
| <p>would return <tt>ok</tt>, where <tt>from != from_end</tt>, then </p> |
| <pre> do_out(state, from, from + 1, from_next, to, to_end, to_next) |
| </pre> |
| <p>must also return <tt>ok</tt>, and that if</p> |
| <pre> do_in(state, from, from_end, from_next, to, to_lim, to_next) |
| </pre> |
| <p>would return <tt>ok</tt>, where <tt>to != to_lim</tt>, then</p> |
| <pre> do_in(state, from, from_end, from_next, to, to + 1, to_next) |
| </pre> |
| <p>must also return <tt>ok</tt>. [<i>Footnote:</i> Informally, this |
| means that <tt>basic_filebuf</tt> assumes that the mapping from |
| internal to external characters is 1 to N: a <tt>codecvt</tt> that is |
| used by <tt>basic_filebuf</tt> must be able to translate characters |
| one internal character at a time. <i>--End Footnote</i>]</p> |
| </blockquote> |
| |
| <p><i>[Redmond: Minor change in proposed resolution. Original |
| proposed resolution talked about "success", with a parenthetical |
| comment that success meant returning <tt>ok</tt>. New wording |
| removes all talk about "success", and just talks about the |
| return value.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| |
| <p>The proposed resoluion says that conversions can be performed one |
| internal character at a time. This rules out some encodings that |
| would otherwise be legal. The alternative answer would mean there |
| would be some internal positions that do not correspond to any |
| external file position.</p> |
| <p> |
| An example of an encoding that this rules out is one where the |
| <tt>internT</tt> and <tt>externT</tt> are of the same type, and |
| where the internal sequence <tt>c1 c2</tt> corresponds to the |
| external sequence <tt>c2 c1</tt>. |
| </p> |
| <p>It was generally agreed that <tt>basic_filebuf</tt> relies |
| on this property: it was designed under the assumption that |
| the external-to-internal mapping is N-to-1, and it is not clear |
| that <tt>basic_filebuf</tt> is implementable without that |
| restriction. |
| </p> |
| <p> |
| The proposed resolution is expressed as a restriction on |
| <tt>codecvt</tt> when used by <tt>basic_filebuf</tt>, rather |
| than a blanket restriction on all <tt>codecvt</tt> facets, |
| because <tt>basic_filebuf</tt> is the only other part of the |
| library that uses <tt>codecvt</tt>. If a user wants to define |
| a <tt>codecvt</tt> facet that implements a more general N-to-M |
| mapping, there is no reason to prohibit it, so long as the user |
| does not expect <tt>basic_filebuf</tt> to be able to use it. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="78"></a>78. Typo: event_call_back</h3> |
| <p><b>Section:</b> 27.4.2 [ios.base] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base">issues</a> in [ios.base].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>typo: event_call_back should be event_callback </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the 27.4.2 [ios.base] synopsis change |
| "event_call_back" to "event_callback". </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="79"></a>79. Inconsistent declaration of polar()</h3> |
| <p><b>Section:</b> 26.3.1 [complex.synopsis], 26.3.7 [complex.value.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#complex.synopsis">issues</a> in [complex.synopsis].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 26.3.1 [complex.synopsis] polar is declared as follows:</p> |
| <pre> template<class T> complex<T> polar(const T&, const T&); </pre> |
| |
| <p>In 26.3.7 [complex.value.ops] it is declared as follows:</p> |
| <pre> template<class T> complex<T> polar(const T& rho, const T& theta = 0); </pre> |
| |
| <p>Thus whether the second parameter is optional is not clear. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 26.3.1 [complex.synopsis] change:</p> |
| <pre> template<class T> complex<T> polar(const T&, const T&);</pre> |
| |
| <p>to:</p> |
| <pre> template<class T> complex<T> polar(const T& rho, const T& theta = 0); </pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="80"></a>80. Global Operators of complex declared twice</h3> |
| <p><b>Section:</b> 26.3.1 [complex.synopsis], 26.3.2 [complex] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#complex.synopsis">issues</a> in [complex.synopsis].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Both 26.2.1 and 26.2.2 contain declarations of global operators for |
| class complex. This redundancy should be removed.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Reduce redundancy according to the general style of the standard. </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="83"></a>83. String::npos vs. string::max_size()</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#89">89</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Many string member functions throw if size is getting or exceeding |
| npos. However, I wonder why they don't throw if size is getting or |
| exceeding max_size() instead of npos. May be npos is known at compile |
| time, while max_size() is known at runtime. However, what happens if |
| size exceeds max_size() but not npos, then? It seems the standard |
| lacks some clarifications here.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>After 21.3 [basic.string] paragraph 4 ("The functions |
| described in this clause...") add a new paragraph:</p> |
| |
| <blockquote> |
| <p>For any string operation, if as a result of the operation, <tt> size()</tt> would exceed |
| <tt> max_size()</tt> then |
| the operation throws <tt>length_error</tt>.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes length_error is the correct exception to throw.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="86"></a>86. String constructors don't describe exceptions</h3> |
| <p><b>Section:</b> 21.3.1 [string.require] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.require">issues</a> in [string.require].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The constructor from a range:</p> |
| |
| <pre>template<class InputIterator> |
| basic_string(InputIterator begin, InputIterator end, |
| const Allocator& a = Allocator());</pre> |
| |
| <p>lacks a throws clause. However, I would expect that it throws |
| according to the other constructors if the numbers of characters in |
| the range equals npos (or exceeds max_size(), see above). </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.1 [string.require], Strike throws paragraphs for |
| constructors which say "Throws: length_error if n == |
| npos."</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Throws clauses for length_error if n == npos are no longer needed |
| because they are subsumed by the general wording added by the |
| resolution for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#83">83</a>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="90"></a>90. Incorrect description of operator >> for strings</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The effect of operator >> for strings contain the following item:</p> |
| |
| <p> <tt>isspace(c,getloc())</tt> is true for the next available input |
| character c.</p> |
| |
| <p>Here <tt>getloc()</tt> has to be replaced by <tt>is.getloc()</tt>. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.8.9 [string.io] paragraph 1 Effects clause replace:</p> |
| |
| <blockquote> |
| <p><tt>isspace(c,getloc())</tt> is true for the next available input character c.</p> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <p><tt>isspace(c,is.getloc())</tt> is true for the next available input character c.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="91"></a>91. Description of operator>> and getline() for string<> might cause endless loop</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Operator >> and getline() for strings read until eof() |
| in the input stream is true. However, this might never happen, if the |
| stream can't read anymore without reaching EOF. So shouldn't it be |
| changed into that it reads until !good() ? </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 21.3.8.9 [string.io], paragraph 1, replace:</p> |
| <blockquote><p> |
| Effects: Begins by constructing a sentry object k as if k were |
| constructed by typename basic_istream<charT,traits>::sentry k( is). If |
| bool( k) is true, it calls str.erase() and then extracts characters |
| from is and appends them to str as if by calling str.append(1, c). If |
| is.width() is greater than zero, the maximum number n of characters |
| appended is is.width(); otherwise n is str.max_size(). Characters are |
| extracted and appended until any of the following occurs: |
| </p></blockquote> |
| <p>with:</p> |
| <blockquote><p> |
| Effects: Behaves as a formatted input function (27.6.1.2.1 |
| [istream.formatted.reqmts]). After constructing a sentry object, if the |
| sentry converts to true, calls str.erase() and then extracts |
| characters from is and appends them to str as if by calling |
| str.append(1,c). If is.width() is greater than zero, the maximum |
| number n of characters appended is is.width(); otherwise n is |
| str.max_size(). Characters are extracted and appended until any of the |
| following occurs: |
| </p></blockquote> |
| |
| <p>In 21.3.8.9 [string.io], paragraph 6, replace</p> |
| <blockquote><p> |
| Effects: Begins by constructing a sentry object k as if by typename |
| basic_istream<charT,traits>::sentry k( is, true). If bool( k) is true, |
| it calls str.erase() and then extracts characters from is and appends |
| them to str as if by calling str.append(1, c) until any of the |
| following occurs: |
| </p></blockquote> |
| <p>with:</p> |
| <blockquote><p>Effects: Behaves as an unformatted input function |
| (27.6.1.3 [istream.unformatted]), except that it does not affect the |
| value returned |
| by subsequent calls to basic_istream<>::gcount(). After |
| constructing a sentry object, if the sentry converts to true, calls |
| str.erase() and then extracts characters from is and appends them to |
| str as if by calling str.append(1,c) until any of the following |
| occurs: |
| </p></blockquote> |
| |
| <p><i>[Redmond: Made changes in proposed resolution. <tt>operator>></tt> |
| should be a formatted input function, not an unformatted input function. |
| <tt>getline</tt> should not be required to set <tt>gcount</tt>, since |
| there is no mechanism for <tt>gcount</tt> to be set except by one of |
| <tt>basic_istream</tt>'s member functions.]</i></p> |
| |
| |
| <p><i>[Curaçao: Nico agrees with proposed resolution.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The real issue here is whether or not these string input functions |
| get their characters from a streambuf, rather than by calling an |
| istream's member functions, a streambuf signals failure either by |
| returning eof or by throwing an exception; there are no other |
| possibilities. The proposed resolution makes it clear that these two |
| functions do get characters from a streambuf.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="92"></a>92. Incomplete Algorithm Requirements</h3> |
| <p><b>Section:</b> 25 [algorithms] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 1998-09-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#algorithms">issues</a> in [algorithms].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The standard does not state, how often a function object is copied, |
| called, or the order of calls inside an algorithm. This may lead to |
| surprising/buggy behavior. Consider the following example: </p> |
| |
| <pre>class Nth { // function object that returns true for the nth element |
| private: |
| int nth; // element to return true for |
| int count; // element counter |
| public: |
| Nth (int n) : nth(n), count(0) { |
| } |
| bool operator() (int) { |
| return ++count == nth; |
| } |
| }; |
| .... |
| // remove third element |
| list<int>::iterator pos; |
| pos = remove_if(coll.begin(),coll.end(), // range |
| Nth(3)), // remove criterion |
| coll.erase(pos,coll.end()); </pre> |
| |
| <p>This call, in fact removes the 3rd <b>AND the 6th</b> element. This |
| happens because the usual implementation of the algorithm copies the |
| function object internally: </p> |
| |
| <pre>template <class ForwIter, class Predicate> |
| ForwIter std::remove_if(ForwIter beg, ForwIter end, Predicate op) |
| { |
| beg = find_if(beg, end, op); |
| if (beg == end) { |
| return beg; |
| } |
| else { |
| ForwIter next = beg; |
| return remove_copy_if(++next, end, beg, op); |
| } |
| } </pre> |
| |
| <p>The algorithm uses find_if() to find the first element that should |
| be removed. However, it then uses a copy of the passed function object |
| to process the resulting elements (if any). Here, Nth is used again |
| and removes also the sixth element. This behavior compromises the |
| advantage of function objects being able to have a state. Without any |
| cost it could be avoided (just implement it directly instead of |
| calling find_if()). </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add a new paragraph following 25 [algorithms] paragraph 8:</p> |
| <blockquote><p> |
| [Note: Unless otherwise specified, algorithms that take function |
| objects as arguments are permitted to copy those function objects |
| freely. Programmers for whom object identity is important should |
| consider using a wrapper class that points to a noncopied |
| implementation object, or some equivalent solution.] |
| </p></blockquote> |
| |
| <p><i>[Dublin: Pete Becker felt that this may not be a defect, |
| but rather something that programmers need to be educated about. |
| There was discussion of adding wording to the effect that the number |
| and order of calls to function objects, including predicates, not |
| affect the behavior of the function object.]</i></p> |
| |
| |
| <p><i>[Pre-Kona: Nico comments: It seems the problem is that we don't |
| have a clear statement of "predicate" in the |
| standard. People including me seemed to think "a function |
| returning a Boolean value and being able to be called by an STL |
| algorithm or be used as sorting criterion or ... is a |
| predicate". But a predicate has more requirements: It should |
| never change its behavior due to a call or being copied. IMHO we have |
| to state this in the standard. If you like, see section 8.1.4 of my |
| library book for a detailed discussion.]</i></p> |
| |
| |
| <p><i>[Kona: Nico will provide wording to the effect that "unless |
| otherwise specified, the number of copies of and calls to function |
| objects by algorithms is unspecified". Consider placing in |
| 25 [algorithms] after paragraph 9.]</i></p> |
| |
| |
| <p><i>[Santa Cruz: The standard doesn't currently guarantee that |
| functions object won't be copied, and what isn't forbidden is |
| allowed. It is believed (especially since implementations that were |
| written in concert with the standard do make copies of function |
| objects) that this was intentional. Thus, no normative change is |
| needed. What we should put in is a non-normative note suggesting to |
| programmers that if they want to guarantee the lack of copying they |
| should use something like the <tt>ref</tt> wrapper.]</i></p> |
| |
| |
| <p><i>[Oxford: Matt provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="98"></a>98. Input iterator requirements are badly written</h3> |
| <p><b>Section:</b> 24.1.1 [input.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> AFNOR <b>Date:</b> 1998-10-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.iterators">issues</a> in [input.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Table 72 in 24.1.1 [input.iterators] specifies semantics for |
| <tt>*r++</tt> of:</p> |
| |
| <p> <tt>{ T tmp = *r; ++r; return tmp; }</tt></p> |
| |
| <p>There are two problems with this. First, the return type is |
| specified to be "T", as opposed to something like "convertible to T". |
| This is too specific: we want to allow *r++ to return an lvalue.</p> |
| |
| <p>Second, writing the semantics in terms of code misleadingly |
| suggests that the effects *r++ should precisely replicate the behavior |
| of this code, including side effects. (Does this mean that *r++ |
| should invoke the copy constructor exactly as many times as the sample |
| code above would?) See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#334">334</a> for a similar |
| problem.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In Table 72 in 24.1.1 [input.iterators], change the return type |
| for <tt>*r++</tt> from <tt>T</tt> to "convertible to T".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This issue has two parts: the return type, and the number of times |
| the copy constructor is invoked.</p> |
| |
| <p>The LWG believes the the first part is a real issue. It's |
| inappropriate for the return type to be specified so much more |
| precisely for *r++ than it is for *r. In particular, if r is of |
| (say) type <tt>int*</tt>, then *r++ isn't <tt>int</tt>, |
| but <tt>int&</tt>.</p> |
| |
| <p>The LWG does not believe that the number of times the copy |
| constructor is invoked is a real issue. This can vary in any case, |
| because of language rules on copy constructor elision. That's too |
| much to read into these semantics clauses.</p> |
| |
| <p>Additionally, as Dave Abrahams pointed out (c++std-lib-13703): since |
| we're told (24.1/3) that forward iterators satisfy all the requirements |
| of input iterators, we can't impose any requirements in the Input |
| Iterator requirements table that forward iterators don't satisfy.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="103"></a>103. set::iterator is required to be modifiable, but this allows modification of keys</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> AFNOR <b>Date:</b> 1998-10-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Set::iterator is described as implementation-defined with a |
| reference to the container requirement; the container requirement says |
| that const_iterator is an iterator pointing to const T and iterator an |
| iterator pointing to T.</p> |
| |
| <p>23.1.2 paragraph 2 implies that the keys should not be modified to |
| break the ordering of elements. But that is not clearly |
| specified. Especially considering that the current standard requires |
| that iterator for associative containers be different from |
| const_iterator. Set, for example, has the following: </p> |
| |
| <p><tt>typedef implementation defined iterator;<br> |
| // See _lib.container.requirements_</tt></p> |
| |
| <p>23.1 [container.requirements] actually requires that iterator type pointing |
| to T (table 65). Disallowing user modification of keys by changing the |
| standard to require an iterator for associative container to be the |
| same as const_iterator would be overkill since that will unnecessarily |
| significantly restrict the usage of associative container. A class to |
| be used as elements of set, for example, can no longer be modified |
| easily without either redesigning the class (using mutable on fields |
| that have nothing to do with ordering), or using const_cast, which |
| defeats requiring iterator to be const_iterator. The proposed solution |
| goes in line with trusting user knows what he is doing. </p> |
| |
| <p><b>Other Options Evaluated:</b> </p> |
| |
| <p>Option A. In 23.1.4 [associative.reqmts], paragraph 2, after |
| first sentence, and before "In addition,...", add one line: |
| </p> |
| |
| <blockquote> |
| <p>Modification of keys shall not change their strict weak ordering. </p> |
| </blockquote> |
| |
| <p>Option B. Add three new sentences to 23.1.4 [associative.reqmts]:</p> |
| |
| <blockquote> |
| <p>At the end of paragraph 5: "Keys in an associative container |
| are immutable." At the end of paragraph 6: "For |
| associative containers where the value type is the same as the key |
| type, both <tt>iterator</tt> and <tt>const_iterator</tt> are |
| constant iterators. It is unspecified whether or not |
| <tt>iterator</tt> and <tt>const_iterator</tt> are the same |
| type."</p> |
| </blockquote> |
| |
| <p>Option C. To 23.1.4 [associative.reqmts], paragraph 3, which |
| currently reads:</p> |
| |
| <blockquote> |
| <p>The phrase ``equivalence of keys'' means the equivalence relation imposed by the |
| comparison and not the operator== on keys. That is, two keys k1 and k2 in the same |
| container are considered to be equivalent if for the comparison object comp, comp(k1, k2) |
| == false && comp(k2, k1) == false.</p> |
| </blockquote> |
| |
| <p> add the following:</p> |
| |
| <blockquote> |
| <p>For any two keys k1 and k2 in the same container, comp(k1, k2) shall return the same |
| value whenever it is evaluated. [Note: If k2 is removed from the container and later |
| reinserted, comp(k1, k2) must still return a consistent value but this value may be |
| different than it was the first time k1 and k2 were in the same container. This is |
| intended to allow usage like a string key that contains a filename, where comp compares |
| file contents; if k2 is removed, the file is changed, and the same k2 (filename) is |
| reinserted, comp(k1, k2) must again return a consistent value but this value may be |
| different than it was the previous time k2 was in the container.]</p> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following to 23.1.4 [associative.reqmts] at |
| the indicated location:</p> |
| |
| <blockquote> |
| <p>At the end of paragraph 3: "For any two keys k1 and k2 in the same container, |
| calling comp(k1, k2) shall always return the same |
| value."</p> |
| <p>At the end of paragraph 5: "Keys in an associative container are immutable."</p> |
| <p>At the end of paragraph 6: "For associative containers where the value type is the |
| same as the key type, both <tt>iterator</tt> and <tt>const_iterator</tt> are constant |
| iterators. It is unspecified whether or not <tt>iterator</tt> and <tt>const_iterator</tt> |
| are the same type."</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Several arguments were advanced for and against allowing set elements to be |
| mutable as long as the ordering was not effected. The argument which swayed the |
| LWG was one of safety; if elements were mutable, there would be no compile-time |
| way to detect of a simple user oversight which caused ordering to be |
| modified. There was a report that this had actually happened in practice, |
| and had been painful to diagnose. If users need to modify elements, |
| it is possible to use mutable members or const_cast.</p> |
| |
| <p>Simply requiring that keys be immutable is not sufficient, because the comparison |
| object may indirectly (via pointers) operate on values outside of the keys.</p> |
| |
| <p> |
| The types <tt>iterator</tt> and <tt>const_iterator</tt> are permitted |
| to be different types to allow for potential future work in which some |
| member functions might be overloaded between the two types. No such |
| member functions exist now, and the LWG believes that user functionality |
| will not be impaired by permitting the two types to be the same. A |
| function that operates on both iterator types can be defined for |
| <tt>const_iterator</tt> alone, and can rely on the automatic |
| conversion from <tt>iterator</tt> to <tt>const_iterator</tt>. |
| </p> |
| |
| <p><i>[Tokyo: The LWG crafted the proposed resolution and rationale.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="106"></a>106. Numeric library private members are implementation defined</h3> |
| <p><b>Section:</b> 26.5.5 [template.slice.array] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> AFNOR <b>Date:</b> 1998-10-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#template.slice.array">issues</a> in [template.slice.array].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>This is the only place in the whole standard where the implementation has to document |
| something private.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove the comment which says "// remainder implementation defined" from: |
| </p> |
| |
| <ul> |
| <li>26.5.5 [template.slice.array]</li> |
| <li>26.5.7 [template.gslice.array]</li> |
| <li>26.5.8 [template.mask.array]</li> |
| <li>26.5.9 [template.indirect.array]</li> |
| </ul> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="108"></a>108. Lifetime of exception::what() return unspecified</h3> |
| <p><b>Section:</b> 18.6.1 [type.info] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> AFNOR <b>Date:</b> 1998-10-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#type.info">issues</a> in [type.info].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 18.6.1, paragraphs 8-9, the lifetime of the return value of |
| exception::what() is left unspecified. This issue has implications |
| with exception safety of exception handling: some exceptions should |
| not throw bad_alloc.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to 18.6.1 [type.info] paragraph 9 (exception::what notes |
| clause) the sentence:</p> |
| |
| <blockquote> |
| <p>The return value remains valid until the exception object from which it is obtained is |
| destroyed or a non-const member function of the exception object is called.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>If an exception object has non-const members, they may be used |
| to set internal state that should affect the contents of the string |
| returned by <tt>what()</tt>. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="109"></a>109. Missing binders for non-const sequence elements</h3> |
| <p><b>Section:</b> D.8 [depr.lib.binders] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bjarne Stroustrup <b>Date:</b> 1998-10-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.lib.binders">issues</a> in [depr.lib.binders].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>There are no versions of binders that apply to non-const elements |
| of a sequence. This makes examples like for_each() using bind2nd() on |
| page 521 of "The C++ Programming Language (3rd)" |
| non-conforming. Suitable versions of the binders need to be added.</p> |
| |
| <p>Further discussion from Nico:</p> |
| |
| <p>What is probably meant here is shown in the following example:</p> |
| |
| <pre>class Elem { |
| public: |
| void print (int i) const { } |
| void modify (int i) { } |
| }; </pre> |
| <pre>int main() |
| { |
| vector<Elem> coll(2); |
| for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Elem::print),42)); // OK |
| for_each (coll.begin(), coll.end(), bind2nd(mem_fun_ref(&Elem::modify),42)); // ERROR |
| }</pre> |
| |
| <p>The error results from the fact that bind2nd() passes its first |
| argument (the argument of the sequence) as constant reference. See the |
| following typical implementation:</p> |
| |
| <blockquote> |
| <pre>template <class Operation> |
| class binder2nd |
| : public unary_function<typename Operation::first_argument_type, |
| typename Operation::result_type> { |
| protected: |
| Operation op; |
| typename Operation::second_argument_type value; |
| public: |
| binder2nd(const Operation& o, |
| const typename Operation::second_argument_type& v) |
| : op(o), value(v) {} </pre> |
| <pre> typename Operation::result_type |
| operator()(const typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| };</pre> |
| </blockquote> |
| |
| <p>The solution is to overload operator () of bind2nd for non-constant arguments:</p> |
| |
| <blockquote> |
| <pre>template <class Operation> |
| class binder2nd |
| : public unary_function<typename Operation::first_argument_type, |
| typename Operation::result_type> { |
| protected: |
| Operation op; |
| typename Operation::second_argument_type value; |
| public: |
| binder2nd(const Operation& o, |
| const typename Operation::second_argument_type& v) |
| : op(o), value(v) {} </pre> |
| <pre> typename Operation::result_type |
| operator()(const typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| typename Operation::result_type |
| operator()(typename Operation::first_argument_type& x) const { |
| return op(x, value); |
| } |
| };</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><b>Howard believes there is a flaw</b> in this resolution. |
| See c++std-lib-9127. We may need to reopen this issue.</p> |
| |
| <p>In D.8 [depr.lib.binders] in the declaration of binder1st after:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(const typename Operation::second_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>insert:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(typename Operation::second_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>In D.8 [depr.lib.binders] in the declaration of binder2nd after:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(const typename Operation::first_argument_type& x) const;</tt></p> |
| </blockquote> |
| <p>insert:</p> |
| <blockquote> |
| <p><tt>typename Operation::result_type<br> |
| operator()(typename Operation::first_argument_type& x) const;</tt></p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG discussed this at some length.It was agreed that |
| this is a mistake in the design, but there was no consensus on whether |
| it was a defect in the Standard. Straw vote: NAD - 5. Accept |
| proposed resolution - 3. Leave open - 6.]</i></p> |
| |
| |
| <p><i>[Copenhagen: It was generally agreed that this was a defect. |
| Strap poll: NAD - 0. Accept proposed resolution - 10. |
| Leave open - 1.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="110"></a>110. istreambuf_iterator::equal not const</h3> |
| <p><b>Section:</b> 24.5.3 [istreambuf.iterator], 24.5.3.5 [istreambuf.iterator::equal] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 1998-10-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istreambuf.iterator">issues</a> in [istreambuf.iterator].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Member istreambuf_iterator<>::equal is not declared |
| "const", yet 24.5.3.6 [istreambuf.iterator::op==] says that operator==, |
| which is const, calls it. This is contradictory. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.3 [istreambuf.iterator] and also in 24.5.3.5 [istreambuf.iterator::equal], |
| replace:</p> |
| |
| <blockquote> |
| <pre>bool equal(istreambuf_iterator& b);</pre> |
| </blockquote> |
| |
| <p>with:</p> |
| |
| <blockquote> |
| <pre>bool equal(const istreambuf_iterator& b) const;</pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="112"></a>112. Minor typo in <tt>ostreambuf_iterator</tt> constructor</h3> |
| <p><b>Section:</b> 24.5.4.1 [ostreambuf.iter.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-10-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The <b>requires</b> clause for <tt>ostreambuf_iterator</tt>'s |
| constructor from an <tt>ostream_type</tt> (24.5.4.1, paragraph 1) |
| reads "<i>s</i> is not null". However, <i>s</i> is a |
| reference, and references can't be null. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.5.4.1 [ostreambuf.iter.cons]:</p> |
| |
| <p>Move the current paragraph 1, which reads "Requires: s is not |
| null.", from the first constructor to the second constructor.</p> |
| |
| <p>Insert a new paragraph 1 Requires clause for the first constructor |
| reading:</p> |
| |
| <blockquote> |
| <p><b>Requires</b>: <tt>s.rdbuf()</tt> is not null.</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="114"></a>114. Placement forms example in error twice</h3> |
| <p><b>Section:</b> 18.5.1.3 [new.delete.placement] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 1998-10-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#new.delete.placement">issues</a> in [new.delete.placement].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#196">196</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Section 18.5.1.3 contains the following example: </p> |
| |
| <pre>[Example: This can be useful for constructing an object at a known address: |
| char place[sizeof(Something)]; |
| Something* p = new (place) Something(); |
| -end example]</pre> |
| |
| <p>First code line: "place" need not have any special alignment, and the |
| following constructor could fail due to misaligned data.</p> |
| |
| <p>Second code line: Aren't the parens on Something() incorrect? [Dublin: the LWG |
| believes the () are correct.]</p> |
| |
| <p>Examples are not normative, but nevertheless should not show code that is invalid or |
| likely to fail.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the first line of code in the example in |
| 18.5.1.3 [new.delete.placement] with: |
| </p> |
| |
| <blockquote> |
| <pre>void* place = operator new(sizeof(Something));</pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="115"></a>115. Typo in strstream constructors</h3> |
| <p><b>Section:</b> D.7.4.1 [depr.strstream.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 1998-11-02</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>D.7.4.1 strstream constructors paragraph 2 says: </p> |
| |
| <blockquote> |
| <p>Effects: Constructs an object of class strstream, initializing the base class with |
| iostream(& sb) and initializing sb with one of the two constructors: </p> |
| <p>- If mode&app==0, then s shall designate the first element of an array of n |
| elements. The constructor is strstreambuf(s, n, s). </p> |
| <p>- If mode&app==0, then s shall designate the first element of an array of n |
| elements that contains an NTBS whose first element is designated by s. The constructor is |
| strstreambuf(s, n, s+std::strlen(s)).</p> |
| </blockquote> |
| |
| <p>Notice the second condition is the same as the first. I think the second condition |
| should be "If mode&app==app", or "mode&app!=0", meaning that |
| the append bit is set.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.7.3.1 [depr.ostrstream.cons] paragraph 2 and D.7.4.1 [depr.strstream.cons] |
| paragraph 2, change the first condition to <tt>(mode&app)==0</tt> |
| and the second condition to <tt>(mode&app)!=0</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="117"></a>117. <tt>basic_ostream</tt> uses nonexistent <tt>num_put</tt> member functions</h3> |
| <p><b>Section:</b> 27.6.2.6.2 [ostream.inserters.arithmetic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-11-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.inserters.arithmetic">issues</a> in [ostream.inserters.arithmetic].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The <b>effects</b> clause for numeric inserters says that |
| insertion of a value <tt>x</tt>, whose type is either <tt>bool</tt>, |
| <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned |
| int</tt>, <tt>long</tt>, <tt>unsigned long</tt>, <tt>float</tt>, |
| <tt>double</tt>, <tt>long double</tt>, or <tt>const void*</tt>, is |
| delegated to <tt>num_put</tt>, and that insertion is performed as if |
| through the following code fragment: </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), val). failed();</pre> |
| |
| <p>This doesn't work, because <tt>num_put<></tt>::put is only |
| overloaded for the types <tt>bool</tt>, <tt>long</tt>, <tt>unsigned |
| long</tt>, <tt>double</tt>, <tt>long double</tt>, and <tt>const |
| void*</tt>. That is, the code fragment in the standard is incorrect |
| (it is diagnosed as ambiguous at compile time) for the types |
| <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, <tt>unsigned |
| int</tt>, and <tt>float</tt>. </p> |
| |
| <p>We must either add new member functions to <tt>num_put</tt>, or |
| else change the description in <tt>ostream</tt> so that it only calls |
| functions that are actually there. I prefer the latter. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 27.6.2.5.2, paragraph 1 with the following: </p> |
| |
| <blockquote> |
| <p> |
| The classes num_get<> and num_put<> handle locale-dependent numeric |
| formatting and parsing. These inserter functions use the imbued |
| locale value to perform numeric formatting. When val is of type bool, |
| long, unsigned long, double, long double, or const void*, the |
| formatting conversion occurs as if it performed the following code |
| fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), val). failed(); |
| </pre> |
| |
| <p> |
| When val is of type short the formatting conversion occurs as if it |
| performed the following code fragment: |
| </p> |
| |
| <pre>ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; |
| bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), |
| baseflags == ios_base::oct || baseflags == ios_base::hex |
| ? static_cast<long>(static_cast<unsigned short>(val)) |
| : static_cast<long>(val)). failed(); |
| </pre> |
| |
| <p> |
| When val is of type int the formatting conversion occurs as if it performed |
| the following code fragment: |
| </p> |
| |
| <pre>ios_base::fmtflags baseflags = ios_base::flags() & ios_base::basefield; |
| bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), |
| baseflags == ios_base::oct || baseflags == ios_base::hex |
| ? static_cast<long>(static_cast<unsigned int>(val)) |
| : static_cast<long>(val)). failed(); |
| </pre> |
| |
| <p> |
| When val is of type unsigned short or unsigned int the formatting conversion |
| occurs as if it performed the following code fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), static_cast<unsigned long>(val)). |
| failed(); |
| </pre> |
| |
| <p> |
| When val is of type float the formatting conversion occurs as if it |
| performed the following code fragment: |
| </p> |
| |
| <pre>bool failed = use_facet< |
| num_put<charT,ostreambuf_iterator<charT,traits> > |
| >(getloc()).put(*this, *this, fill(), static_cast<double>(val)). |
| failed(); |
| </pre> |
| |
| </blockquote> |
| |
| <p><i>[post-Toronto: This differs from the previous proposed |
| resolution; PJP provided the new wording. The differences are in |
| signed short and int output.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution was to cast int and short to long, |
| unsigned int and unsigned short to unsigned long, and float to double, |
| thus ensuring that we don't try to use nonexistent num_put<> |
| member functions. The current proposed resolution is more |
| complicated, but gives more expected results for hex and octal output |
| of signed short and signed int. (On a system with 16-bit short, for |
| example, printing short(-1) in hex format should yield 0xffff.)</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="118"></a>118. <tt>basic_istream</tt> uses nonexistent <tt>num_get</tt> member functions</h3> |
| <p><b>Section:</b> 27.6.1.2.2 [istream.formatted.arithmetic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1998-11-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.formatted.arithmetic">issues</a> in [istream.formatted.arithmetic].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Formatted input is defined for the types <tt>short</tt>, <tt>unsigned short</tt>, <tt>int</tt>, |
| <tt>unsigned int</tt>, <tt>long</tt>, <tt>unsigned long</tt>, <tt>float</tt>, <tt>double</tt>, |
| <tt>long double</tt>, <tt>bool</tt>, and <tt>void*</tt>. According to section 27.6.1.2.2, |
| formatted input of a value <tt>x</tt> is done as if by the following code fragment: </p> |
| |
| <pre>typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| use_facet< numget >(loc).get(*this, 0, *this, err, val); |
| setstate(err);</pre> |
| |
| <p>According to section 22.2.2.1.1 [facet.num.get.members], however, |
| <tt>num_get<>::get()</tt> is only overloaded for the types |
| <tt>bool</tt>, <tt>long</tt>, <tt>unsigned short</tt>, <tt>unsigned |
| int</tt>, <tt>unsigned long</tt>, <tt>unsigned long</tt>, |
| <tt>float</tt>, <tt>double</tt>, <tt>long double</tt>, and |
| <tt>void*</tt>. Comparing the lists from the two sections, we find |
| that 27.6.1.2.2 is using a nonexistent function for types |
| <tt>short</tt> and <tt>int</tt>. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.2.2 [istream.formatted.arithmetic] Arithmetic Extractors, remove the |
| two lines (1st and 3rd) which read:</p> |
| <blockquote> |
| <pre>operator>>(short& val); |
| ... |
| operator>>(int& val);</pre> |
| </blockquote> |
| |
| <p>And add the following at the end of that section (27.6.1.2.2) :</p> |
| |
| <blockquote> |
| <pre>operator>>(short& val);</pre> |
| <p>The conversion occurs as if performed by the following code fragment (using |
| the same notation as for the preceding code fragment):</p> |
| <pre> typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet< numget >(loc).get(*this, 0, *this, err, lval); |
| if (err == 0 |
| && (lval < numeric_limits<short>::min() || numeric_limits<short>::max() < lval)) |
| err = ios_base::failbit; |
| setstate(err);</pre> |
| <pre>operator>>(int& val);</pre> |
| <p>The conversion occurs as if performed by the following code fragment (using |
| the same notation as for the preceding code fragment):</p> |
| <pre> typedef num_get< charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet< numget >(loc).get(*this, 0, *this, err, lval); |
| if (err == 0 |
| && (lval < numeric_limits<int>::min() || numeric_limits<int>::max() < lval)) |
| err = ios_base::failbit; |
| setstate(err);</pre> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: PJP provided the above wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="119"></a>119. Should virtual functions be allowed to strengthen the exception specification?</h3> |
| <p><b>Section:</b> 17.4.4.9 [res.on.exception.handling] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#res.on.exception.handling">issues</a> in [res.on.exception.handling].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 17.4.4.9 [res.on.exception.handling] states: </p> |
| |
| <p>"An implementation may strengthen the exception-specification |
| for a function by removing listed exceptions." </p> |
| |
| <p>The problem is that if an implementation is allowed to do this for |
| virtual functions, then a library user cannot write a class that |
| portably derives from that class. </p> |
| |
| <p>For example, this would not compile if ios_base::failure::~failure |
| had an empty exception specification: </p> |
| |
| <pre>#include <ios> |
| #include <string> |
| |
| class D : public std::ios_base::failure { |
| public: |
| D(const std::string&); |
| ~D(); // error - exception specification must be compatible with |
| // overridden virtual function ios_base::failure::~failure() |
| };</pre> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Section 17.4.4.9 [res.on.exception.handling] from:</p> |
| |
| <p> "may strengthen the |
| exception-specification for a function"</p> |
| |
| <p>to:</p> |
| |
| <p> "may strengthen the |
| exception-specification for a non-virtual function". </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="120"></a>120. Can an implementor add specializations?</h3> |
| <p><b>Section:</b> 17.4.3.2 [reserved.names] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#reserved.names">issues</a> in [reserved.names].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>The original issue asked whether a library implementor could |
| specialize standard library templates for built-in types. (This was |
| an issue because users are permitted to explicitly instantiate |
| standard library templates.)</p> |
| |
| <p>Specializations are no longer a problem, because of the resolution |
| to core issue 259. Under the proposed resolution, it will be legal |
| for a translation unit to contain both a specialization and an |
| explicit instantiation of the same template, provided that the |
| specialization comes first. In such a case, the explicit |
| instantiation will be ignored. Further discussion of library issue |
| 120 assumes that the core 259 resolution will be adopted.</p> |
| |
| <p>However, as noted in lib-7047, one piece of this issue still |
| remains: what happens if a standard library implementor explicitly |
| instantiates a standard library templates? It's illegal for a program |
| to contain two different explicit instantiations of the same template |
| for the same type in two different translation units (ODR violation), |
| and the core working group doesn't believe it is practical to relax |
| that restriction.</p> |
| |
| <p>The issue, then, is: are users allowed to explicitly instantiate |
| standard library templates for non-user defined types? The status quo |
| answer is 'yes'. Changing it to 'no' would give library implementors |
| more freedom.</p> |
| |
| <p>This is an issue because, for performance reasons, library |
| implementors often need to explicitly instantiate standard library |
| templates. (for example, std::basic_string<char>) Does giving |
| users freedom to explicitly instantiate standard library templates for |
| non-user defined types make it impossible or painfully difficult for |
| library implementors to do this?</p> |
| |
| <p>John Spicer suggests, in lib-8957, that library implementors have a |
| mechanism they can use for explicit instantiations that doesn't |
| prevent users from performing their own explicit instantiations: put |
| each explicit instantiation in its own object file. (Different |
| solutions might be necessary for Unix DSOs or MS-Windows DLLs.) On |
| some platforms, library implementors might not need to do anything |
| special: the "undefined behavior" that results from having two |
| different explicit instantiations might be harmless.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Append to 17.4.3.2 [reserved.names] paragraph 1: </p> |
| <blockquote><p> |
| A program may explicitly instantiate any templates in the standard |
| library only if the declaration depends on the name of a user-defined |
| type of external linkage and the instantiation meets the standard library |
| requirements for the original template. |
| </p></blockquote> |
| |
| <p><i>[Kona: changed the wording from "a user-defined name" to "the name of |
| a user-defined type"]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered another possible resolution:</p> |
| <blockquote> |
| <p>In light of the resolution to core issue 259, no normative changes |
| in the library clauses are necessary. Add the following non-normative |
| note to the end of 17.4.3.2 [reserved.names] paragraph 1:</p> |
| <blockquote><p> |
| [<i>Note:</i> A program may explicitly instantiate standard library |
| templates, even when an explicit instantiation does not depend on |
| a user-defined name. <i>--end note</i>] |
| </p></blockquote> |
| </blockquote> |
| |
| <p>The LWG rejected this because it was believed that it would make |
| it unnecessarily difficult for library implementors to write |
| high-quality implementations. A program may not include an |
| explicit instantiation of the same template, for the same template |
| arguments, in two different translation units. If users are |
| allowed to provide explicit instantiations of Standard Library |
| templates for built-in types, then library implementors aren't, |
| at least not without nonportable tricks.</p> |
| |
| <p>The most serious problem is a class template that has writeable |
| static member variables. Unfortunately, such class templates are |
| important and, in existing Standard Library implementations, are |
| often explicitly specialized by library implementors: locale facets, |
| which have a writeable static member variable <tt>id</tt>. If a |
| user's explicit instantiation collided with the implementations |
| explicit instantiation, iostream initialization could cause locales |
| to be constructed in an inconsistent state.</p> |
| |
| <p>One proposed implementation technique was for Standard Library |
| implementors to provide explicit instantiations in separate object |
| files, so that they would not be picked up by the linker when the |
| user also provides an explicit instantiation. However, this |
| technique only applies for Standard Library implementations that |
| are packaged as static archives. Most Standard Library |
| implementations nowadays are packaged as dynamic libraries, so this |
| technique would not apply.</p> |
| |
| <p>The Committee is now considering standardization of dynamic |
| linking. If there are such changes in the future, it may be |
| appropriate to revisit this issue later.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="122"></a>122. streambuf/wstreambuf description should not say they are specializations</h3> |
| <p><b>Section:</b> 27.5.2 [streambuf] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#streambuf">issues</a> in [streambuf].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 27.5.2 describes the streambuf classes this way: </p> |
| |
| <blockquote> |
| |
| <p>The class streambuf is a specialization of the template class basic_streambuf |
| specialized for the type char. </p> |
| |
| <p>The class wstreambuf is a specialization of the template class basic_streambuf |
| specialized for the type wchar_t. </p> |
| |
| </blockquote> |
| |
| <p>This implies that these classes must be template specializations, not typedefs. </p> |
| |
| <p>It doesn't seem this was intended, since Section 27.5 has them declared as typedefs. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 27.5.2 [streambuf] paragraphs 2 and 3 (the above two |
| sentences). </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The <tt>streambuf</tt> synopsis already has a declaration for the |
| typedefs and that is sufficient. </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="123"></a>123. Should valarray helper arrays fill functions be const?</h3> |
| <p><b>Section:</b> 26.5.5.3 [slice.arr.fill], 26.5.7.3 [gslice.array.fill], 26.5.8.3 [mask.array.fill], 26.5.9.3 [indirect.array.fill] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>One of the operator= in the valarray helper arrays is const and one |
| is not. For example, look at slice_array. This operator= in Section |
| 26.5.5.1 [slice.arr.assign] is const: </p> |
| |
| <p> <tt>void operator=(const valarray<T>&) const;</tt> </p> |
| |
| <p>but this one in Section 26.5.5.3 [slice.arr.fill] is not: </p> |
| |
| <p> <tt>void operator=(const T&); </tt></p> |
| |
| <p>The description of the semantics for these two functions is similar. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>26.5.5 [template.slice.array] Template class slice_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for slice_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.5.3 [slice.arr.fill] slice_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.7 [template.gslice.array] Template class gslice_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for gslice_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.7.3 [gslice.array.fill] gslice_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.8 [template.mask.array] Template class mask_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for mask_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.8.3 [mask.array.fill] mask_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.9 [template.indirect.array] Template class indirect_array</p> |
| <blockquote> |
| |
| <p>In the class template definition for indirect_array, replace the member |
| function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>with</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| <p>26.5.9.3 [indirect.array.fill] indirect_array fill function</p> |
| <blockquote> |
| |
| <p>Change the function declaration</p> |
| <pre> void operator=(const T&); |
| </pre> |
| <p>to</p> |
| <pre> void operator=(const T&) const; |
| </pre> |
| </blockquote> |
| |
| |
| <p><i>[Redmond: Robert provided wording.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>There's no good reason for one version of operator= being const and |
| another one not. Because of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#253">253</a>, this now |
| matters: these functions are now callable in more circumstances. In |
| many existing implementations, both versions are already const.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="124"></a>124. ctype_byname<charT>::do_scan_is & do_scan_not return type should be const charT*</h3> |
| <p><b>Section:</b> 22.2.1.2 [locale.ctype.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.ctype.byname">issues</a> in [locale.ctype.byname].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In Section 22.2.1.2 [locale.ctype.byname] |
| ctype_byname<charT>::do_scan_is() and do_scan_not() are declared |
| to return a const char* not a const charT*. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Section 22.2.1.2 [locale.ctype.byname] <tt>do_scan_is()</tt> and |
| <tt>do_scan_not()</tt> to return a <tt> const |
| charT*</tt>. </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="125"></a>125. valarray<T>::operator!() return type is inconsistent</h3> |
| <p><b>Section:</b> 26.5.2 [template.valarray] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#template.valarray">issues</a> in [template.valarray].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In Section 26.5.2 [template.valarray] valarray<T>::operator!() |
| is |
| declared to return a valarray<T>, but in Section 26.5.2.5 |
| [valarray.unary] it is declared to return a valarray<bool>. The |
| latter appears to be correct. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change in Section 26.5.2 [template.valarray] the declaration of |
| <tt>operator!()</tt> so that the return type is |
| <tt>valarray<bool></tt>. </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="126"></a>126. typos in Effects clause of ctype::do_narrow()</h3> |
| <p><b>Section:</b> 22.2.1.1.2 [locale.ctype.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.ctype.virtuals">issues</a> in [locale.ctype.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p><p>Typos in 22.2.1.1.2 need to be fixed.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In Section 22.2.1.1.2 [locale.ctype.virtuals] change: </p> |
| |
| <pre> do_widen(do_narrow(c),0) == c</pre> |
| |
| <p>to:</p> |
| |
| <pre> do_widen(do_narrow(c,0)) == c</pre> |
| |
| <p>and change:</p> |
| |
| <pre> (is(M,c) || !ctc.is(M, do_narrow(c),dfault) )</pre> |
| |
| <p>to:</p> |
| |
| <pre> (is(M,c) || !ctc.is(M, do_narrow(c,dfault)) )</pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="127"></a>127. auto_ptr<> conversion issues</h3> |
| <p><b>Section:</b> D.9.1 [auto.ptr] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Greg Colvin <b>Date:</b> 1999-02-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#auto.ptr">issues</a> in [auto.ptr].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>There are two problems with the current <tt>auto_ptr</tt> wording |
| in the standard: </p> |
| |
| <p>First, the <tt>auto_ptr_ref</tt> definition cannot be nested |
| because <tt>auto_ptr<Derived>::auto_ptr_ref</tt> is unrelated to |
| <tt>auto_ptr<Base>::auto_ptr_ref</tt>. <i>Also submitted by |
| Nathan Myers, with the same proposed resolution.</i></p> |
| |
| <p>Second, there is no <tt>auto_ptr</tt> assignment operator taking an |
| <tt>auto_ptr_ref</tt> argument. </p> |
| |
| <p>I have discussed these problems with my proposal coauthor, Bill |
| Gibbons, and with some compiler and library implementors, and we |
| believe that these problems are not desired or desirable implications |
| of the standard. </p> |
| |
| <p>25 Aug 1999: The proposed resolution now reflects changes suggested |
| by Dave Abrahams, with Greg Colvin's concurrence; 1) changed |
| "assignment operator" to "public assignment |
| operator", 2) changed effects to specify use of release(), 3) |
| made the conversion to auto_ptr_ref const. </p> |
| |
| <p>2 Feb 2000: Lisa Lippincott comments: [The resolution of] this issue |
| states that the conversion from auto_ptr to auto_ptr_ref should |
| be const. This is not acceptable, because it would allow |
| initialization and assignment from _any_ const auto_ptr! It also |
| introduces an implementation difficulty in writing this conversion |
| function -- namely, somewhere along the line, a const_cast will be |
| necessary to remove that const so that release() may be called. This |
| may result in undefined behavior [7.1.5.1/4]. The conversion |
| operator does not have to be const, because a non-const implicit |
| object parameter may be bound to an rvalue [13.3.3.1.4/3] |
| [13.3.1/5]. </p> |
| |
| <p>Tokyo: The LWG removed the following from the proposed resolution:</p> |
| |
| <p>In 20.5.4 [meta.unary], paragraph 2, and 20.5.4.3 [meta.unary.prop], |
| paragraph 2, make the conversion to auto_ptr_ref const:</p> |
| <blockquote> |
| <pre>template<class Y> operator auto_ptr_ref<Y>() const throw();</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.5.4 [meta.unary], paragraph 2, move |
| the <tt>auto_ptr_ref</tt> definition to namespace scope.</p> |
| |
| <p>In 20.5.4 [meta.unary], paragraph 2, add |
| a public assignment operator to the <tt>auto_ptr</tt> definition: </p> |
| |
| <blockquote> |
| <pre>auto_ptr& operator=(auto_ptr_ref<X> r) throw();</pre> |
| </blockquote> |
| |
| <p>Also add the assignment operator to 20.5.4.3 [meta.unary.prop]: </p> |
| |
| <blockquote> |
| <pre>auto_ptr& operator=(auto_ptr_ref<X> r) throw()</pre> |
| |
| <p><b>Effects:</b> Calls <tt>reset(p.release())</tt> for the <tt>auto_ptr |
| p</tt> that <tt>r</tt> holds a reference to.<br> |
| <b>Returns: </b><tt>*this</tt>.</p> |
| |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="129"></a>129. Need error indication from seekp() and seekg()</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted], 27.6.2.5 [ostream.seeks] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 1999-02-22</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Currently, the standard does not specify how seekg() and seekp() |
| indicate failure. They are not required to set failbit, and they can't |
| return an error indication because they must return *this, i.e. the |
| stream. Hence, it is undefined what happens if they fail. And they |
| <i>can</i> fail, for instance, when a file stream is disconnected from the |
| underlying file (is_open()==false) or when a wide character file |
| stream must perform a state-dependent code conversion, etc. </p> |
| |
| <p>The stream functions seekg() and seekp() should set failbit in the |
| stream state in case of failure.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the Effects: clause of seekg() in |
| 27.6.1.3 [istream.unformatted] and to the Effects: clause of seekp() in |
| 27.6.2.5 [ostream.seeks]: </p> |
| |
| <blockquote> |
| <p>In case of failure, the function calls <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt>). |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Setting failbit is the usual error reporting mechanism for streams</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="130"></a>130. Return type of container::erase(iterator) differs for associative containers</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts], 23.1.3 [sequence.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1999-03-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#451">451</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Table 67 (23.1.1) says that container::erase(iterator) returns an |
| iterator. Table 69 (23.1.2) says that in addition to this requirement, |
| associative containers also say that container::erase(iterator) |
| returns void. That's not an addition; it's a change to the |
| requirements, which has the effect of making associative containers |
| fail to meet the requirements for containers.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| In 23.1.4 [associative.reqmts], in Table 69 Associative container |
| requirements, change the return type of <tt>a.erase(q)</tt> from |
| <tt>void</tt> to <tt>iterator</tt>. Change the |
| assertion/not/pre/post-condition from "erases the element pointed to |
| by <tt>q</tt>" to "erases the element pointed to by <tt>q</tt>. |
| Returns an iterator pointing to the element immediately following q |
| prior to the element being erased. If no such element exists, a.end() |
| is returned." |
| </p> |
| |
| <p> |
| In 23.1.4 [associative.reqmts], in Table 69 Associative container |
| requirements, change the return type of <tt>a.erase(q1, q2)</tt> |
| from <tt>void</tt> to <tt>iterator</tt>. Change the |
| assertion/not/pre/post-condition from "erases the elements in the |
| range <tt>[q1, q2)</tt>" to "erases the elements in the range <tt>[q1, |
| q2)</tt>. Returns q2." |
| </p> |
| |
| <p> |
| In 23.3.1 [map], in the <tt>map</tt> class synopsis; and |
| in 23.3.2 [multimap], in the <tt>multimap</tt> class synopsis; and |
| in 23.3.3 [set], in the <tt>set</tt> class synopsis; and |
| in 23.3.4 [multiset], in the <tt>multiset</tt> class synopsis: |
| change the signature of the first <tt>erase</tt> overload to |
| </p> |
| <pre> iterator erase(iterator position); |
| </pre> |
| <p>and change the signature of the third <tt>erase</tt> overload to</p> |
| <pre> iterator erase(iterator first, iterator last); |
| </pre> |
| |
| |
| <p><i>[Pre-Kona: reopened at the request of Howard Hinnant]</i></p> |
| |
| |
| <p><i>[Post-Kona: the LWG agrees the return type should be |
| <tt>iterator</tt>, not <tt>void</tt>. (Alex Stepanov agrees too.) |
| Matt provided wording.]</i></p> |
| |
| |
| <p><i>[ |
| Sydney: the proposed wording went in the right direction, but it |
| wasn't good enough. We want to return an iterator from the range form |
| of erase as well as the single-iterator form. Also, the wording is |
| slightly different from the wording we have for sequences; there's no |
| good reason for having a difference. Matt provided new wording, |
| (reflected above) which we will review at the next meeting. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Redmond: formally voted into WP. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="132"></a>132. list::resize description uses random access iterators</h3> |
| <p><b>Section:</b> 23.2.4.2 [list.capacity] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-03-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description reads:</p> |
| |
| <p>-1- Effects:</p> |
| |
| <pre> if (sz > size()) |
| insert(end(), sz-size(), c); |
| else if (sz < size()) |
| erase(begin()+sz, end()); |
| else |
| ; // do nothing</pre> |
| |
| <p>Obviously list::resize should not be specified in terms of random access iterators.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.4.2 [list.capacity] paragraph 1 to:</p> |
| |
| <p>Effects:</p> |
| |
| <pre> if (sz > size()) |
| insert(end(), sz-size(), c); |
| else if (sz < size()) |
| { |
| iterator i = begin(); |
| advance(i, sz); |
| erase(i, end()); |
| }</pre> |
| |
| <p><i>[Dublin: The LWG asked Howard to discuss exception safety offline |
| with David Abrahams. They had a discussion and believe there is |
| no issue of exception safety with the proposed resolution.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="133"></a>133. map missing get_allocator()</h3> |
| <p><b>Section:</b> 23.3.1 [map] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-03-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#map">issues</a> in [map].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p><p>The title says it all.</p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert in 23.3.1 [map], paragraph 2, |
| after operator= in the map declaration:</p> |
| |
| <pre> allocator_type get_allocator() const;</pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="134"></a>134. vector constructors over specified</h3> |
| <p><b>Section:</b> 23.2.6.1 [vector.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-03-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The complexity description says: "It does at most 2N calls to the copy constructor |
| of T and logN reallocations if they are just input iterators ...".</p> |
| |
| <p>This appears to be overly restrictive, dictating the precise memory/performance |
| tradeoff for the implementor.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.6.1 [vector.cons], paragraph 1 to:</p> |
| |
| <p>-1- Complexity: The constructor template <class |
| InputIterator> vector(InputIterator first, InputIterator last) |
| makes only N calls to the copy constructor of T (where N is the |
| distance between first and last) and no reallocations if iterators |
| first and last are of forward, bidirectional, or random access |
| categories. It makes order N calls to the copy constructor of T and |
| order logN reallocations if they are just input iterators. |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>"at most 2N calls" is correct only if the growth factor |
| is greater than or equal to 2. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="136"></a>136. seekp, seekg setting wrong streams?</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-03-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>I may be misunderstanding the intent, but should not seekg set only |
| the input stream and seekp set only the output stream? The description |
| seems to say that each should set both input and output streams. If |
| that's really the intent, I withdraw this proposal.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 27.6.1.3 change:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(pos_type pos); |
| Effects: If fail() != true, executes rdbuf()->pubseekpos(pos). </pre> |
| |
| <p>To:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(pos_type pos); |
| Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_base::in). </pre> |
| |
| <p>In section 27.6.1.3 change:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(off_type& off, ios_base::seekdir dir); |
| Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir). </pre> |
| |
| <p>To:</p> |
| |
| <pre>basic_istream<charT,traits>& seekg(off_type& off, ios_base::seekdir dir); |
| Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_base::in). </pre> |
| |
| <p>In section 27.6.2.4, paragraph 2 change:</p> |
| |
| <pre>-2- Effects: If fail() != true, executes rdbuf()->pubseekpos(pos). </pre> |
| |
| <p>To:</p> |
| |
| <pre>-2- Effects: If fail() != true, executes rdbuf()->pubseekpos(pos, ios_base::out). </pre> |
| |
| <p>In section 27.6.2.4, paragraph 4 change:</p> |
| |
| <pre>-4- Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir). </pre> |
| |
| <p>To:</p> |
| |
| <pre>-4- Effects: If fail() != true, executes rdbuf()->pubseekoff(off, dir, ios_base::out). </pre> |
| |
| <p><i>[Dublin: Dietmar Kühl thinks this is probably correct, but would |
| like the opinion of more iostream experts before taking action.]</i></p> |
| |
| |
| <p><i>[Tokyo: Reviewed by the LWG. PJP noted that although his docs are |
| incorrect, his implementation already implements the Proposed |
| Resolution.]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: Matt Austern comments:<br> |
| Is it a problem with basic_istream and basic_ostream, or is it a problem |
| with basic_stringbuf? |
| We could resolve the issue either by changing basic_istream and |
| basic_ostream, or by changing basic_stringbuf. I prefer the latter |
| change (or maybe both changes): I don't see any reason for the standard to |
| require that std::stringbuf s(std::string("foo"), std::ios_base::in); |
| s.pubseekoff(0, std::ios_base::beg); must fail.<br> |
| This requirement is a bit weird. There's no similar requirement |
| for basic_streambuf<>::seekpos, or for basic_filebuf<>::seekoff or |
| basic_filebuf<>::seekpos.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="137"></a>137. Do use_facet and has_facet look in the global locale?</h3> |
| <p><b>Section:</b> 22.1.1 [locale] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 1999-03-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale">issues</a> in [locale].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 22.1.1 [locale] says:</p> |
| |
| <p>-4- In the call to use_facet<Facet>(loc), the type argument |
| chooses a facet, making available all members of the named type. If |
| Facet is not present in a locale (or, failing that, in the global |
| locale), it throws the standard exception bad_cast. A C++ program can |
| check if a locale implements a particular facet with the template |
| function has_facet<Facet>(). </p> |
| |
| <p>This contradicts the specification given in section |
| 22.1.2 [locale.global.templates]: |
| <br><br> |
| template <class Facet> const Facet& use_facet(const |
| locale& loc); <br> |
| <br> |
| -1- Get a reference to a facet of a locale. <br> |
| -2- Returns: a reference to the corresponding facet of loc, if present. <br> |
| -3- Throws: bad_cast if has_facet<Facet>(loc) is false. <br> |
| -4- Notes: The reference returned remains valid at least as long as any copy of loc exists |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the phrase "(or, failing that, in the global locale)" |
| from section 22.1.1. </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Needed for consistency with the way locales are handled elsewhere |
| in the standard.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="139"></a>139. Optional sequence operation table description unclear</h3> |
| <p><b>Section:</b> 23.1.3 [sequence.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1999-03-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The sentence introducing the Optional sequence operation table |
| (23.1.1 paragraph 12) has two problems:</p> |
| |
| <p>A. It says ``The operations in table 68 are provided only for the containers for which |
| they take constant time.''<br> |
| <br> |
| That could be interpreted in two ways, one of them being ``Even though table 68 shows |
| particular operations as being provided, implementations are free to omit them if they |
| cannot implement them in constant time.''<br> |
| <br> |
| B. That paragraph says nothing about amortized constant time, and it should. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the wording in 23.1.1 paragraph 12 which begins ``The operations in table 68 are provided only..." |
| with:</p> |
| |
| <blockquote> |
| <p>Table 68 lists sequence operations that are provided for some types of sequential |
| containers but not others. An implementation shall provide these operations for all |
| container types shown in the ``container'' column, and shall implement them so as to take |
| amortized constant time.</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="141"></a>141. basic_string::find_last_of, find_last_not_of say pos instead of xpos</h3> |
| <p><b>Section:</b> 21.3.6.4 [string::insert], 21.3.6.6 [string::replace] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Arch Robison <b>Date:</b> 1999-04-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::insert">issues</a> in [string::insert].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Sections 21.3.6.4 paragraph 1 and 21.3.6.6 paragraph 1 surely have misprints where they |
| say:<br> |
| <br> |
| — <tt>xpos <= pos</tt> and <tt>pos < size();</tt></p> |
| |
| <p>Surely the document meant to say ``<tt>xpos < size()</tt>'' in both places.</p> |
| |
| <p><i>[Judy Ward also sent in this issue for 21.3.6.4 with the same |
| proposed resolution.]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change Sections 21.3.6.4 paragraph 1 and 21.3.6.6 paragraph 1, the line which says:<br> |
| <br> |
| — <tt>xpos <= pos</tt> and <tt>pos < size();<br> |
| <br> |
| </tt>to:<br> |
| <tt><br> |
| </tt>— <tt>xpos <= pos</tt> and <tt>xpos < size();</tt></p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="142"></a>142. lexicographical_compare complexity wrong</h3> |
| <p><b>Section:</b> 25.3.8 [alg.lex.comparison] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-06-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The lexicographical_compare complexity is specified as:<br> |
| <br> |
| "At most min((last1 - first1), (last2 - first2)) |
| applications of the corresponding comparison."<br> |
| <br> |
| The best I can do is twice that expensive.</p> |
| |
| <p>Nicolai Josuttis comments in lib-6862: You mean, to check for |
| equality you have to check both < and >? Yes, IMO you are |
| right! (and Matt states this complexity in his book)</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.3.8 [alg.lex.comparison] complexity to:</p> |
| <blockquote><p> |
| At most <tt>2*min((last1 - first1), (last2 - first2))</tt> |
| applications of the corresponding comparison. |
| </p></blockquote> |
| |
| <p>Change the example at the end of paragraph 3 to read:</p> |
| <blockquote><p> |
| [Example:<br> |
| <br> |
| for ( ; first1 != last1 && first2 != last2 ; |
| ++first1, ++first2) {<br> |
| if (*first1 < *first2) return true;<br> |
| if (*first2 < *first1) return false;<br> |
| }<br> |
| return first1 == last1 && first2 != last2;<br> |
| <br> |
| --end example] |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="144"></a>144. Deque constructor complexity wrong </h3> |
| <p><b>Section:</b> 23.2.2.1 [deque.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Herb Sutter <b>Date:</b> 1999-05-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#deque.cons">issues</a> in [deque.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 23.2.2.1 [deque.cons] paragraph 6, the deque ctor that takes an iterator range appears |
| to have complexity requirements which are incorrect, and which contradict the |
| complexity requirements for insert(). I suspect that the text in question, |
| below, was taken from vector:</p> |
| <blockquote> |
| <p>Complexity: If the iterators first and last are forward iterators, |
| bidirectional iterators, or random access iterators the constructor makes only |
| N calls to the copy constructor, and performs no reallocations, where N is |
| last - first.</p> |
| </blockquote> |
| <p>The word "reallocations" does not really apply to deque. Further, |
| all of the following appears to be spurious:</p> |
| <blockquote> |
| <p>It makes at most 2N calls to the copy constructor of T and log N |
| reallocations if they are input iterators.1)</p> |
| <p>1) The complexity is greater in the case of input iterators because each |
| element must be added individually: it is impossible to determine the distance |
| between first abd last before doing the copying.</p> |
| </blockquote> |
| <p>This makes perfect sense for vector, but not for deque. Why should deque gain |
| an efficiency advantage from knowing in advance the number of elements to |
| insert?</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.2.1 [deque.cons] paragraph 6, replace the Complexity description, including the |
| footnote, with the following text (which also corrects the "abd" |
| typo):</p> |
| <blockquote> |
| <p>Complexity: Makes last - first calls to the copy constructor of T.</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="146"></a>146. complex<T> Inserter and Extractor need sentries</h3> |
| <p><b>Section:</b> 26.3.6 [complex.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 1999-05-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#complex.ops">issues</a> in [complex.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The extractor for complex numbers is specified as: </p> |
| |
| <blockquote> |
| |
| <p> template<class T, class charT, class traits> <br> |
| basic_istream<charT, traits>& <br> |
| operator>>(basic_istream<charT, traits>& is, complex<T>& x);<br> |
| <br> |
| Effects: Extracts a complex number x of the form: u, (u), or (u,v), |
| where u is the real part and v is the imaginary part |
| (lib.istream.formatted). <br> |
| Requires: The input values be convertible to T. If bad input is |
| encountered, calls is.setstate(ios::failbit) (which may throw |
| ios::failure (lib.iostate.flags). <br> |
| Returns: is .</p> |
| |
| </blockquote> |
| <p>Is it intended that the extractor for complex numbers does not skip |
| whitespace, unlike all other extractors in the standard library do? |
| Shouldn't a sentry be used? <br> |
| <br> |
| The inserter for complex numbers is specified as:</p> |
| |
| <blockquote> |
| |
| <p> template<class T, class charT, class traits> <br> |
| basic_ostream<charT, traits>& <br> |
| operator<<(basic_ostream<charT, traits>& o, const complex<T>& x);<br> |
| <br> |
| Effects: inserts the complex number x onto the stream o as if it were implemented as follows:<br> |
| <br> |
| template<class T, class charT, class traits> <br> |
| basic_ostream<charT, traits>& <br> |
| operator<<(basic_ostream<charT, traits>& o, const complex<T>& x) <br> |
| { <br> |
| basic_ostringstream<charT, traits> s; <br> |
| s.flags(o.flags()); <br> |
| s.imbue(o.getloc()); <br> |
| s.precision(o.precision()); <br> |
| s << '(' << x.real() << "," << x.imag() << ')'; <br> |
| return o << s.str(); <br> |
| }</p> |
| |
| </blockquote> |
| |
| <p>Is it intended that the inserter for complex numbers ignores the |
| field width and does not do any padding? If, with the suggested |
| implementation above, the field width were set in the stream then the |
| opening parentheses would be adjusted, but the rest not, because the |
| field width is reset to zero after each insertion.</p> |
| |
| <p>I think that both operations should use sentries, for sake of |
| consistency with the other inserters and extractors in the |
| library. Regarding the issue of padding in the inserter, I don't know |
| what the intent was. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>After 26.3.6 [complex.ops] paragraph 14 (operator>>), add a |
| Notes clause:</p> |
| |
| <blockquote> |
| |
| <p>Notes: This extraction is performed as a series of simpler |
| extractions. Therefore, the skipping of whitespace is specified to be the |
| same for each of the simpler extractions.</p> |
| |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>For extractors, the note is added to make it clear that skipping whitespace |
| follows an "all-or-none" rule.</p> |
| |
| <p>For inserters, the LWG believes there is no defect; the standard is correct |
| as written.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="147"></a>147. Library Intro refers to global functions that aren't global</h3> |
| <p><b>Section:</b> 17.4.4.3 [global.functions] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Lois Goldthwaite <b>Date:</b> 1999-06-04</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#global.functions">issues</a> in [global.functions].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The library had many global functions until 17.4.1.1 [lib.contents] |
| paragraph 2 was added: </p> |
| |
| <blockquote> |
| |
| <p>All library entities except macros, operator new and operator |
| delete are defined within the namespace std or namespaces nested |
| within namespace std. </p> |
| |
| </blockquote> |
| |
| <p>It appears "global function" was never updated in the following: </p> |
| |
| <blockquote> |
| |
| <p>17.4.4.3 - Global functions [lib.global.functions]<br> |
| <br> |
| -1- It is unspecified whether any global functions in the C++ Standard |
| Library are defined as inline (dcl.fct.spec).<br> |
| <br> |
| -2- A call to a global function signature described in Clauses |
| lib.language.support through lib.input.output behaves the same as if |
| the implementation declares no additional global function |
| signatures.*<br> |
| <br> |
| [Footnote: A valid C++ program always calls the expected library |
| global function. An implementation may also define additional |
| global functions that would otherwise not be called by a valid C++ |
| program. --- end footnote]<br> |
| <br> |
| -3- A global function cannot be declared by the implementation as |
| taking additional default arguments. <br> |
| <br> |
| 17.4.4.4 - Member functions [lib.member.functions]<br> |
| <br> |
| -2- An implementation can declare additional non-virtual member |
| function signatures within a class: </p> |
| |
| <blockquote> |
| |
| <p>-- by adding arguments with default values to a member function |
| signature; The same latitude does not extend to the implementation of |
| virtual or global functions, however. </p> |
| |
| </blockquote> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> Change "global" to "global or non-member" in:</p> |
| <blockquote> |
| <p>17.4.4.3 [lib.global.functions] section title,<br> |
| 17.4.4.3 [lib.global.functions] para 1,<br> |
| 17.4.4.3 [lib.global.functions] para 2 in 2 places plus 2 |
| places in the footnote,<br> |
| 17.4.4.3 [lib.global.functions] para 3,<br> |
| 17.4.4.4 [lib.member.functions] para 2</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Because operator new and delete are global, the proposed resolution |
| was changed from "non-member" to "global or non-member. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="148"></a>148. Functions in the example facet BoolNames should be const</h3> |
| <p><b>Section:</b> 22.2.8 [facets.examples] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Jeremy Siek <b>Date:</b> 1999-06-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facets.examples">issues</a> in [facets.examples].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 22.2.8 [facets.examples] paragraph 13, the do_truename() and |
| do_falsename() functions in the example facet BoolNames should be |
| const. The functions they are overriding in |
| numpunct_byname<char> are const. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.8 [facets.examples] paragraph 13, insert "const" in |
| two places:</p> |
| <blockquote> |
| <p><tt>string do_truename() const { return "Oui Oui!"; }<br> |
| string do_falsename() const { return "Mais Non!"; }</tt></p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="150"></a>150. Find_first_of says integer instead of iterator </h3> |
| <p><b>Section:</b> 25.1.7 [alg.find.first.of] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt McClure <b>Date:</b> 1999-06-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.find.first.of">issues</a> in [alg.find.first.of].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.1.7 [alg.find.first.of] paragraph 2 from:</p> |
| |
| <blockquote> |
| <p>Returns: The first iterator i in the range [first1, last1) such |
| that for some integer j in the range [first2, last2) ...</p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Returns: The first iterator i in the range [first1, last1) such |
| that for some iterator j in the range [first2, last2) ...</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="151"></a>151. Can't currently clear() empty container</h3> |
| <p><b>Section:</b> 23.1.3 [sequence.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Ed Brey <b>Date:</b> 1999-06-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>For both sequences and associative containers, a.clear() has the |
| semantics of erase(a.begin(),a.end()), which is undefined for an empty |
| container since erase(q1,q2) requires that q1 be dereferenceable |
| (23.1.1,3 and 23.1.2,7). When the container is empty, a.begin() is |
| not dereferenceable.<br> |
| <br> |
| The requirement that q1 be unconditionally dereferenceable causes many |
| operations to be intuitively undefined, of which clearing an empty |
| container is probably the most dire.<br> |
| <br> |
| Since q1 and q2 are only referenced in the range [q1, q2), and [q1, |
| q2) is required to be a valid range, stating that q1 and q2 must be |
| iterators or certain kinds of iterators is unnecessary. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.1.1, paragraph 3, change:</p> |
| <blockquote> |
| <p>p and q2 denote valid iterators to a, q and q1 denote valid dereferenceable iterators to a, [q1, q2) denotes a valid range</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>p denotes a valid iterator to a, q denotes a valid dereferenceable iterator to a, [q1, q2) denotes a valid range |
| in a</p> |
| </blockquote> |
| <p>In 23.1.2, paragraph 7, change:</p> |
| <blockquote> |
| <p>p and q2 are valid iterators to a, q and q1 are valid dereferenceable |
| iterators to a, [q1, q2) is a valid range</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>p is a valid iterator to a, q is a valid dereferenceable iterator to a, [q1, q2) is a valid range |
| into a</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="152"></a>152. Typo in <tt>scan_is()</tt> semantics</h3> |
| <p><b>Section:</b> 22.2.1.1.2 [locale.ctype.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.ctype.virtuals">issues</a> in [locale.ctype.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The semantics of <tt>scan_is()</tt> (paragraphs 4 and 6) is not exactly described |
| because there is no function <tt>is()</tt> which only takes a character as |
| argument. Also, in the effects clause (paragraph 3), the semantic is also kept |
| vague.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.1.1.2 [locale.ctype.virtuals] paragraphs 4 and 6, change the returns |
| clause from:</p> |
| <blockquote> |
| <p>"... such that <tt>is(*p)</tt> |
| would..."</p> |
| </blockquote> |
| <p>to: "... such that <tt>is(m, *p)</tt> |
| would...."</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="153"></a>153. Typo in <tt>narrow()</tt> semantics</h3> |
| <p><b>Section:</b> 22.2.1.3.2 [facet.ctype.char.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.ctype.char.members">issues</a> in [facet.ctype.char.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#207">207</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The description of the array version of <tt>narrow()</tt> (in |
| paragraph 11) is flawed: There is no member <tt>do_narrow()</tt> which |
| takes only three arguments because in addition to the range a default |
| character is needed.</p> |
| |
| <p>Additionally, for both <tt>widen</tt> and <tt>narrow</tt> we have |
| two signatures followed by a <b>Returns</b> clause that only addresses |
| one of them.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the returns clause in 22.2.1.3.2 [facet.ctype.char.members] |
| paragraph 10 from:</p> |
| <p> Returns: do_widen(low, high, to).</p> |
| |
| <p>to:</p> |
| <p> Returns: do_widen(c) or do_widen(low, high, to), |
| respectively.</p> |
| |
| <p>Change 22.2.1.3.2 [facet.ctype.char.members] paragraph 10 and 11 from:</p> |
| <pre> char narrow(char c, char /*dfault*/) const; |
| const char* narrow(const char* low, const char* high, |
| char /*dfault*/, char* to) const;</pre> |
| <pre> Returns: do_narrow(low, high, to).</pre> |
| <p>to:</p> |
| <pre> char narrow(char c, char dfault) const; |
| const char* narrow(const char* low, const char* high, |
| char dfault, char* to) const;</pre> |
| <pre> Returns: do_narrow(c, dfault) or |
| do_narrow(low, high, dfault, to), respectively.</pre> |
| |
| <p><i>[Kona: 1) the problem occurs in additional places, 2) a user |
| defined version could be different.]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: Dietmar provided the above wording at the request of |
| the LWG. He could find no other places the problem occurred. He |
| asks for clarification of the Kona "a user defined |
| version..." comment above. Perhaps it was a circuitous way of |
| saying "dfault" needed to be uncommented?]</i></p> |
| |
| |
| <p><i>[Post-Toronto: the issues list maintainer has merged in the |
| proposed resolution from issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#207">207</a>, which addresses the |
| same paragraphs.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="154"></a>154. Missing <tt>double</tt> specifier for <tt>do_get()</tt></h3> |
| <p><b>Section:</b> 22.2.2.1.2 [facet.num.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The table in paragraph 7 for the length modifier does not list the length |
| modifier <tt>l</tt> to be applied if the type is <tt>double</tt>. Thus, the |
| standard asks the implementation to do undefined things when using <tt>scanf()</tt> |
| (the missing length modifier for <tt>scanf()</tt> when scanning <tt>double</tt>s |
| is actually a problem I found quite often in production code, too).</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.2 [facet.num.get.virtuals], paragraph 7, add a row in the Length |
| Modifier table to say that for <tt>double</tt> a length modifier |
| <tt>l</tt> is to be used.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The standard makes an embarrassing beginner's mistake.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="155"></a>155. Typo in naming the class defining the class <tt>Init</tt></h3> |
| <p><b>Section:</b> 27.3 [iostream.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostream.objects">issues</a> in [iostream.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>There are conflicting statements about where the class |
| <tt>Init</tt> is defined. According to 27.3 [iostream.objects] paragraph 2 |
| it is defined as <tt>basic_ios::Init</tt>, according to 27.4.2 [ios.base] it is defined as <tt>ios_base::Init</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.3 [iostream.objects] paragraph 2 from |
| "<tt>basic_ios::Init"</tt> to |
| "<tt>ios_base::Init"</tt>.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Although not strictly wrong, the standard was misleading enough to warrant |
| the change.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="156"></a>156. Typo in <tt>imbue()</tt> description</h3> |
| <p><b>Section:</b> 27.4.2.3 [ios.base.locales] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios.base.locales">issues</a> in [ios.base.locales].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>There is a small discrepancy between the declarations of |
| <tt>imbue()</tt>: in 27.4.2 [ios.base] the argument is passed as |
| <tt>locale const&</tt> (correct), in 27.4.2.3 [ios.base.locales] it |
| is passed as <tt>locale const</tt> (wrong).</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.4.2.3 [ios.base.locales] change the <tt>imbue</tt> argument |
| from "<tt>locale const" to "locale |
| const&".</tt></p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="158"></a>158. Underspecified semantics for <tt>setbuf()</tt></h3> |
| <p><b>Section:</b> 27.5.2.4.2 [streambuf.virt.buffer] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#streambuf.virt.buffer">issues</a> in [streambuf.virt.buffer].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The default behavior of <tt>setbuf()</tt> is described only for the |
| situation that <tt>gptr() != 0 && gptr() != egptr()</tt>: |
| namely to do nothing. What has to be done in other situations |
| is not described although there is actually only one reasonable |
| approach, namely to do nothing, too.</p> |
| |
| <p>Since changing the buffer would almost certainly mess up most |
| buffer management of derived classes unless these classes do it |
| themselves, the default behavior of <tt>setbuf()</tt> should always be |
| to do nothing.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.4.2 [streambuf.virt.buffer], paragraph 3, Default behavior, |
| to: "Default behavior: Does nothing. Returns this."</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="159"></a>159. Strange use of <tt>underflow()</tt></h3> |
| <p><b>Section:</b> 27.5.2.4.3 [streambuf.virt.get] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description of the meaning of the result of |
| <tt>showmanyc()</tt> seems to be rather strange: It uses calls to |
| <tt>underflow()</tt>. Using <tt>underflow()</tt> is strange because |
| this function only reads the current character but does not extract |
| it, <tt>uflow()</tt> would extract the current character. This should |
| be fixed to use <tt>sbumpc()</tt> instead.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.5.2.4.3 [streambuf.virt.get] paragraph 1, |
| <tt>showmanyc()</tt>returns clause, by replacing the word |
| "supplied" with the words "extracted from the |
| stream".</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="160"></a>160. Typo: Use of non-existing function <tt>exception()</tt></h3> |
| <p><b>Section:</b> 27.6.1.1 [istream] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream">issues</a> in [istream].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The paragraph 4 refers to the function <tt>exception()</tt> which |
| is not defined. Probably, the referred function is |
| <tt>basic_ios<>::exceptions()</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.1 [istream], 27.6.1.3 [istream.unformatted], paragraph 1, |
| 27.6.2.1 [ostream], paragraph 3, and 27.6.2.6.1 [ostream.formatted.reqmts], |
| paragraph 1, change "<tt>exception()" to |
| "exceptions()"</tt>.</p> |
| |
| <p><i>[Note to Editor: "exceptions" with an "s" |
| is the correct spelling.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="161"></a>161. Typo: <tt>istream_iterator</tt> vs. <tt>istreambuf_iterator</tt></h3> |
| <p><b>Section:</b> 27.6.1.2.2 [istream.formatted.arithmetic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.formatted.arithmetic">issues</a> in [istream.formatted.arithmetic].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The note in the second paragraph pretends that the first argument |
| is an object of type <tt>istream_iterator</tt>. This is wrong: It is |
| an object of type <tt>istreambuf_iterator</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.6.1.2.2 [istream.formatted.arithmetic] from:</p> |
| <blockquote> |
| <p>The first argument provides an object of the istream_iterator class...</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>The first argument provides an object of the istreambuf_iterator class...</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="164"></a>164. do_put() has apparently unused fill argument</h3> |
| <p><b>Section:</b> 22.2.5.3.2 [locale.time.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 1999-07-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 22.2.5.3.2 [locale.time.put.virtuals] the do_put() function is specified |
| as taking a fill character as an argument, but the description of the |
| function does not say whether the character is used at all and, if so, |
| in which way. The same holds for any format control parameters that |
| are accessible through the ios_base& argument, such as the |
| adjustment or the field width. Is strftime() supposed to use the fill |
| character in any way? In any case, the specification of |
| time_put.do_put() looks inconsistent to me.<br> <br> Is the |
| signature of do_put() wrong, or is the effects clause incomplete?</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following note after 22.2.5.3.2 [locale.time.put.virtuals] |
| paragraph 2:</p> |
| <blockquote> |
| <p> [Note: the <tt>fill</tt> argument may be used in the implementation-defined formats, or by derivations. A space character is a reasonable default |
| for this argument. --end Note]</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG felt that while the normative text was correct, |
| users need some guidance on what to pass for the <tt>fill</tt> |
| argument since the standard doesn't say how it's used.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="165"></a>165. <tt>xsputn()</tt>, <tt>pubsync()</tt> never called by <tt>basic_ostream</tt> members?</h3> |
| <p><b>Section:</b> 27.6.2.1 [ostream] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream">issues</a> in [ostream].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 2 explicitly states that none of the <tt>basic_ostream</tt> |
| functions falling into one of the groups "formatted output functions" |
| and "unformatted output functions" calls any stream buffer function |
| which might call a virtual function other than <tt>overflow()</tt>. Basically |
| this is fine but this implies that <tt>sputn()</tt> (this function would call |
| the virtual function <tt>xsputn()</tt>) is never called by any of the standard |
| output functions. Is this really intended? At minimum it would be convenient to |
| call <tt>xsputn()</tt> for strings... Also, the statement that <tt>overflow()</tt> |
| is the only virtual member of <tt>basic_streambuf</tt> called is in conflict |
| with the definition of <tt>flush()</tt> which calls <tt>rdbuf()->pubsync()</tt> |
| and thereby the virtual function <tt>sync()</tt> (<tt>flush()</tt> is listed |
| under "unformatted output functions").</p> |
| <p>In addition, I guess that the sentence starting with "They may use other |
| public members of <tt>basic_ostream</tt> ..." probably was intended to |
| start with "They may use other public members of <tt>basic_streamuf</tt>..." |
| although the problem with the virtual members exists in both cases.</p> |
| <p>I see two obvious resolutions:</p> |
| <ol> |
| <li>state in a footnote that this means that <tt>xsputn()</tt> will never be |
| called by any ostream member and that this is intended.</li> |
| <li>relax the restriction and allow calling <tt>overflow()</tt> and <tt>xsputn()</tt>. |
| Of course, the problem with <tt>flush()</tt> has to be resolved in some way.</li> |
| </ol> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the last sentence of 27.6.2.1 (lib.ostream) paragraph 2 from:</p> |
| <blockquote> |
| <p>They may use other public members of basic_ostream except that they do not |
| invoke any virtual members of rdbuf() except overflow().</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>They may use other public members of basic_ostream except that they shall |
| not invoke any virtual members of rdbuf() except overflow(), xsputn(), and |
| sync().</p> |
| </blockquote> |
| |
| <p><i>[Kona: the LWG believes this is a problem. Wish to ask Jerry or |
| PJP why the standard is written this way.]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: Dietmar supplied wording at the request of the |
| LWG. He comments: The rules can be made a little bit more specific if |
| necessary be explicitly spelling out what virtuals are allowed to be |
| called from what functions and eg to state specifically that flush() |
| is allowed to call sync() while other functions are not.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="167"></a>167. Improper use of <tt>traits_type::length()</tt></h3> |
| <p><b>Section:</b> 27.6.2.6.4 [ostream.inserters.character] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.inserters.character">issues</a> in [ostream.inserters.character].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 4 states that the length is determined using |
| <tt>traits::length(s)</tt>. Unfortunately, this function is not |
| defined for example if the character type is <tt>wchar_t</tt> and the |
| type of <tt>s</tt> is <tt>char const*</tt>. Similar problems exist if |
| the character type is <tt>char</tt> and the type of <tt>s</tt> is |
| either <tt>signed char const*</tt> or <tt>unsigned char |
| const*</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 27.6.2.6.4 [ostream.inserters.character] paragraph 4 from:</p> |
| <blockquote> |
| <p>Effects: Behaves like an formatted inserter (as described in |
| lib.ostream.formatted.reqmts) of out. After a sentry object is |
| constructed it inserts characters. The number of characters starting |
| at s to be inserted is traits::length(s). Padding is determined as |
| described in lib.facet.num.put.virtuals. The traits::length(s) |
| characters starting at s are widened using out.widen |
| (lib.basic.ios.members). The widened characters and any required |
| padding are inserted into out. Calls width(0).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Effects: Behaves like a formatted inserter (as described in |
| lib.ostream.formatted.reqmts) of out. After a sentry object is |
| constructed it inserts <i>n</i> characters starting at <i>s</i>, |
| where <i>n</i> is the number that would be computed as if by:</p> |
| <ul> |
| <li>traits::length(s) for the overload where the first argument is of |
| type basic_ostream<charT, traits>& and the second is |
| of type const charT*, and also for the overload where the first |
| argument is of type basic_ostream<char, traits>& and |
| the second is of type const char*.</li> |
| <li>std::char_traits<char>::length(s) |
| for the overload where the first argument is of type |
| basic_ostream<charT, traits>& and the second is of type |
| const char*.</li> |
| <li>traits::length(reinterpret_cast<const char*>(s)) |
| for the other two overloads.</li> |
| </ul> |
| <p>Padding is determined as described in |
| lib.facet.num.put.virtuals. The <i>n</i> characters starting at |
| <i>s</i> are widened using out.widen (lib.basic.ios.members). The |
| widened characters and any required padding are inserted into |
| out. Calls width(0).</p> |
| </blockquote> |
| |
| <p><i>[Santa Cruz: Matt supplied new wording]</i></p> |
| |
| |
| <p><i>[Kona: changed "where <i>n</i> is" to " where <i>n</i> is the |
| number that would be computed as if by"]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>We have five separate cases. In two of them we can use the |
| user-supplied traits class without any fuss. In the other three we |
| try to use something as close to that user-supplied class as possible. |
| In two cases we've got a traits class that's appropriate for |
| char and what we've got is a const signed char* or a const |
| unsigned char*; that's close enough so we can just use a reinterpret |
| cast, and continue to use the user-supplied traits class. Finally, |
| there's one case where we just have to give up: where we've got a |
| traits class for some arbitrary charT type, and we somehow have to |
| deal with a const char*. There's nothing better to do but fall back |
| to char_traits<char></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="168"></a>168. Typo: formatted vs. unformatted</h3> |
| <p><b>Section:</b> 27.6.2.7 [ostream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.unformatted">issues</a> in [ostream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The first paragraph begins with a descriptions what has to be done |
| in <i>formatted</i> output functions. Probably this is a typo and the |
| paragraph really want to describe unformatted output functions...</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.2.7 [ostream.unformatted] paragraph 1, the first and last |
| sentences, change the word "formatted" to |
| "unformatted":</p> |
| <blockquote> |
| <p>"Each <b>unformatted </b> output function begins ..."<br> |
| "... value specified for the <b>unformatted </b> output |
| function."</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="169"></a>169. Bad efficiency of <tt>overflow()</tt> mandated</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 8, Notes, of this section seems to mandate an extremely |
| inefficient way of buffer handling for <tt>basic_stringbuf</tt>, |
| especially in view of the restriction that <tt>basic_ostream</tt> |
| member functions are not allowed to use <tt>xsputn()</tt> (see 27.6.2.1 [ostream]): For each character to be inserted, a new buffer |
| is to be created.</p> |
| <p>Of course, the resolution below requires some handling of |
| simultaneous input and output since it is no longer possible to update |
| <tt>egptr()</tt> whenever <tt>epptr()</tt> is changed. A possible |
| solution is to handle this in <tt>underflow()</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.7.1.4 [stringbuf.virtuals] paragraph 8, Notes, insert the words |
| "at least" as in the following:</p> |
| <blockquote> |
| <p>To make a write position available, the function reallocates (or initially |
| allocates) an array object with a sufficient number of elements to hold the |
| current array object (if any), plus <b>at least</b> one additional write |
| position.</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="170"></a>170. Inconsistent definition of <tt>traits_type</tt></h3> |
| <p><b>Section:</b> 27.7.4 [stringstream] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The classes <tt>basic_stringstream</tt> (27.7.4 [stringstream]), |
| <tt>basic_istringstream</tt> (27.7.2 [istringstream]), and |
| <tt>basic_ostringstream</tt> (27.7.3 [ostringstream]) are inconsistent |
| in their definition of the type <tt>traits_type</tt>: For |
| <tt>istringstream</tt>, this type is defined, for the other two it is |
| not. This should be consistent.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><b>Proposed resolution:</b></p> <p>To the declarations of |
| <tt>basic_ostringstream</tt> (27.7.3 [ostringstream]) and |
| <tt>basic_stringstream</tt> (27.7.4 [stringstream]) add:</p> |
| <blockquote> |
| <pre>typedef traits traits_type;</pre> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="171"></a>171. Strange <tt>seekpos()</tt> semantics due to joint position</h3> |
| <p><b>Section:</b> 27.8.1.5 [filebuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#filebuf.virtuals">issues</a> in [filebuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Overridden virtual functions, seekpos()</p> <p>In 27.8.1.1 [filebuf] paragraph 3, it is stated that a joint input and |
| output position is maintained by <tt>basic_filebuf</tt>. Still, the |
| description of <tt>seekpos()</tt> seems to talk about different file |
| positions. In particular, it is unclear (at least to me) what is |
| supposed to happen to the output buffer (if there is one) if only the |
| input position is changed. The standard seems to mandate that the |
| output buffer is kept and processed as if there was no positioning of |
| the output position (by changing the input position). Of course, this |
| can be exactly what you want if the flag <tt>ios_base::ate</tt> is |
| set. However, I think, the standard should say something like |
| this:</p> |
| <ul> |
| <li>If <tt>(which & mode) == 0</tt> neither read nor write position is |
| changed and the call fails. Otherwise, the joint read and write position is |
| altered to correspond to <tt>sp</tt>.</li> |
| <li>If there is an output buffer, the output sequences is updated and any |
| unshift sequence is written before the position is altered.</li> |
| <li>If there is an input buffer, the input sequence is updated after the |
| position is altered.</li> |
| </ul> |
| <p>Plus the appropriate error handling, that is...</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the unnumbered paragraph in 27.8.1.4 (lib.filebuf.virtuals) before |
| paragraph 14 from:</p> |
| <blockquote> |
| <p>pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | |
| ios_base::out);</p> |
| <p>Alters the file position, if possible, to correspond to the position stored |
| in sp (as described below).</p> |
| <p>- if (which&ios_base::in)!=0, set the file position to sp, then update |
| the input sequence</p> |
| <p>- if (which&ios_base::out)!=0, then update the output sequence, write |
| any unshift sequence, and set the file position to sp.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | |
| ios_base::out);</p> |
| <p>Alters the file position, if possible, to correspond to the position stored |
| in sp (as described below). Altering the file position performs as follows:</p> |
| <p>1. if (om & ios_base::out)!=0, then update the output sequence and |
| write any unshift sequence;</p> |
| <p>2. set the file position to sp;</p> |
| <p>3. if (om & ios_base::in)!=0, then update the input sequence;</p> |
| <p>where om is the open mode passed to the last call to open(). The operation |
| fails if is_open() returns false.</p> |
| </blockquote> |
| |
| <p><i>[Kona: Dietmar is working on a proposed resolution.]</i></p> |
| |
| <p><i>[Post-Tokyo: Dietmar supplied the above wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="172"></a>172. Inconsistent types for <tt>basic_istream::ignore()</tt></h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Greg Comeau, Dietmar Kühl <b>Date:</b> 1999-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 27.6.1.1 [istream] the function |
| <tt>ignore()</tt> gets an object of type <tt>streamsize</tt> as first |
| argument. However, in 27.6.1.3 [istream.unformatted] |
| paragraph 23 the first argument is of type <tt>int.</tt></p> |
| |
| <p>As far as I can see this is not really a contradiction because |
| everything is consistent if <tt>streamsize</tt> is typedef to be |
| <tt>int</tt>. However, this is almost certainly not what was |
| intended. The same thing happened to <tt>basic_filebuf::setbuf()</tt>, |
| as described in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#173">173</a>.</p> |
| |
| <p>Darin Adler also |
| submitted this issue, commenting: Either 27.6.1.1 should be modified |
| to show a first parameter of type int, or 27.6.1.3 should be modified |
| to show a first parameter of type streamsize and use |
| numeric_limits<streamsize>::max.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.6.1.3 [istream.unformatted] paragraph 23 and 24, change both uses |
| of <tt>int</tt> in the description of <tt>ignore()</tt> to |
| <tt>streamsize</tt>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="173"></a>173. Inconsistent types for <tt>basic_filebuf::setbuf()</tt></h3> |
| <p><b>Section:</b> 27.8.1.5 [filebuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Greg Comeau, Dietmar Kühl <b>Date:</b> 1999-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#filebuf.virtuals">issues</a> in [filebuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| In 27.8.1.1 [filebuf] the function <tt>setbuf()</tt> gets an |
| object of type <tt>streamsize</tt> as second argument. However, in |
| 27.8.1.5 [filebuf.virtuals] paragraph 9 the second argument is of type |
| <tt>int</tt>. |
| </p> |
| |
| <p> |
| As far as I can see this is not really a contradiction because |
| everything is consistent if <tt>streamsize</tt> is typedef to be |
| <tt>int</tt>. However, this is almost certainly not what was |
| intended. The same thing happened to <tt>basic_istream::ignore()</tt>, |
| as described in issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#172">172</a>. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.5 [filebuf.virtuals] paragraph 9, change all uses of |
| <tt>int</tt> in the description of <tt>setbuf()</tt> to |
| <tt>streamsize</tt>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="174"></a>174. Typo: <tt>OFF_T</tt> vs. <tt>POS_T</tt></h3> |
| <p><b>Section:</b> D.6 [depr.ios.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.ios.members">issues</a> in [depr.ios.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>According to paragraph 1 of this section, <tt>streampos</tt> is the |
| type <tt>OFF_T</tt>, the same type as <tt>streamoff</tt>. However, in |
| paragraph 6 the <tt>streampos</tt> gets the type <tt>POS_T</tt></p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change D.6 [depr.ios.members] paragraph 1 from "<tt>typedef |
| OFF_T streampos;</tt>" to "<tt>typedef POS_T |
| streampos;</tt>"</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="175"></a>175. Ambiguity for <tt>basic_streambuf::pubseekpos()</tt> and a few other functions.</h3> |
| <p><b>Section:</b> D.6 [depr.ios.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.ios.members">issues</a> in [depr.ios.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>According to paragraph 8 of this section, the methods |
| <tt>basic_streambuf::pubseekpos()</tt>, |
| <tt>basic_ifstream::open()</tt>, and <tt>basic_ofstream::open</tt> |
| "may" be overloaded by a version of this function taking the |
| type <tt>ios_base::open_mode</tt> as last argument argument instead of |
| <tt>ios_base::openmode</tt> (<tt>ios_base::open_mode</tt> is defined |
| in this section to be an alias for one of the integral types). The |
| clause specifies, that the last argument has a default argument in |
| three cases. However, this generates an ambiguity with the overloaded |
| version because now the arguments are absolutely identical if the last |
| argument is not specified.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.6 [depr.ios.members] paragraph 8, remove the default arguments for |
| <tt>basic_streambuf::pubseekpos()</tt>, |
| <tt>basic_ifstream::open()</tt>, and |
| <tt>basic_ofstream::open().</tt></p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="176"></a>176. <tt>exceptions()</tt> in <tt>ios_base</tt>...?</h3> |
| <p><b>Section:</b> D.6 [depr.ios.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 1999-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.ios.members">issues</a> in [depr.ios.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The "overload" for the function <tt>exceptions()</tt> in |
| paragraph 8 gives the impression that there is another function of |
| this function defined in class <tt>ios_base</tt>. However, this is not |
| the case. Thus, it is hard to tell how the semantics (paragraph 9) can |
| be implemented: "Call the corresponding member function specified |
| in clause 27 [input.output]."</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In D.6 [depr.ios.members] paragraph 8, move the declaration of the |
| function <tt>exceptions()</tt>into class <tt>basic_ios</tt>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="179"></a>179. Comparison of const_iterators to iterators doesn't work</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 1998-07-02</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Currently the following will not compile on two well-known standard |
| library implementations:</p> |
| |
| <blockquote> |
| <pre>#include <set> |
| using namespace std; |
| |
| void f(const set<int> &s) |
| { |
| set<int>::iterator i; |
| if (i==s.end()); // s.end() returns a const_iterator |
| }</pre> |
| </blockquote> |
| |
| <p> |
| The reason this doesn't compile is because operator== was implemented |
| as a member function of the nested classes set:iterator and |
| set::const_iterator, and there is no conversion from const_iterator to |
| iterator. Surprisingly, (s.end() == i) does work, though, because of |
| the conversion from iterator to const_iterator. |
| </p> |
| |
| <p> |
| I don't see a requirement anywhere in the standard that this must |
| work. Should there be one? If so, I think the requirement would need |
| to be added to the tables in section 24.1.1. I'm not sure about the |
| wording. If this requirement existed in the standard, I would think |
| that implementors would have to make the comparison operators |
| non-member functions.</p> |
| |
| <p>This issues was also raised on comp.std.c++ by Darin |
| Adler. The example given was:</p> |
| |
| <blockquote> |
| <pre>bool check_equal(std::deque<int>::iterator i, |
| std::deque<int>::const_iterator ci) |
| { |
| return i == ci; |
| }</pre> |
| </blockquote> |
| |
| <p>Comment from John Potter:</p> |
| <blockquote> |
| <p> |
| In case nobody has noticed, accepting it will break reverse_iterator. |
| </p> |
| |
| <p> |
| The fix is to make the comparison operators templated on two types. |
| </p> |
| |
| <pre> template <class Iterator1, class Iterator2> |
| bool operator== (reverse_iterator<Iterator1> const& x, |
| reverse_iterator<Iterator2> const& y); |
| </pre> |
| |
| <p> |
| Obviously: return x.base() == y.base(); |
| </p> |
| |
| <p> |
| Currently, no reverse_iterator to const_reverse_iterator compares are |
| valid. |
| </p> |
| |
| <p> |
| BTW, I think the issue is in support of bad code. Compares should be |
| between two iterators of the same type. All std::algorithms require |
| the begin and end iterators to be of the same type. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert this paragraph after 23.1 [container.requirements] paragraph 7:</p> |
| <blockquote> |
| <p>In the expressions</p> |
| <pre> i == j |
| i != j |
| i < j |
| i <= j |
| i >= j |
| i > j |
| i - j |
| </pre> |
| <p>Where i and j denote objects of a container's iterator type, |
| either or both may be replaced by an object of the container's |
| const_iterator type referring to the same element with no |
| change in semantics.</p> |
| </blockquote> |
| |
| <p><i>[post-Toronto: Judy supplied a proposed resolution saying that |
| <tt>iterator</tt> and <tt>const_iterator</tt> could be freely mixed in |
| iterator comparison and difference operations.]</i></p> |
| |
| |
| <p><i>[Redmond: Dave and Howard supplied a new proposed resolution which |
| explicitly listed expressions; there was concern that the previous |
| proposed resolution was too informal.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The LWG believes it is clear that the above wording applies only to |
| the nested types <tt>X::iterator</tt> and <tt>X::const_iterator</tt>, |
| where <tt>X</tt> is a container. There is no requirement that |
| <tt>X::reverse_iterator</tt> and <tt>X::const_reverse_iterator</tt> |
| can be mixed. If mixing them is considered important, that's a |
| separate issue. (Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#280">280</a>.) |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="181"></a>181. make_pair() unintended behavior</h3> |
| <p><b>Section:</b> 20.2.3 [pairs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1999-08-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#pairs">issues</a> in [pairs].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The claim has surfaced in Usenet that expressions such as<br> |
| <br> |
| <tt>make_pair("abc", 3)</tt><br> |
| <br> |
| are illegal, notwithstanding their use in examples, because template instantiation tries to bind the first template |
| parameter to <tt> const char (&)[4]</tt>, which type is uncopyable.<br> |
| <br> |
| I doubt anyone intended that behavior... |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.2 [utility], paragraph 1 change the following |
| declaration of make_pair():</p> |
| <blockquote> |
| <pre>template <class T1, class T2> pair<T1,T2> make_pair(const T1&, const T2&);</pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> pair<T1,T2> make_pair(T1, T2);</pre> |
| </blockquote> |
| <p> In 20.2.3 [pairs] paragraph 7 and the line before, change:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> |
| pair<T1, T2> make_pair(const T1& x, const T2& y);</pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>template <class T1, class T2> |
| pair<T1, T2> make_pair(T1 x, T2 y);</pre> |
| </blockquote> |
| <p>and add the following footnote to the effects clause:</p> |
| <blockquote> |
| <p> According to 12.8 [class.copy], an implementation is permitted |
| to not perform a copy of an argument, thus avoiding unnecessary |
| copies.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Two potential fixes were suggested by Matt Austern and Dietmar |
| Kühl, respectively, 1) overloading with array arguments, and 2) use of |
| a reference_traits class with a specialization for arrays. Andy |
| Koenig suggested changing to pass by value. In discussion, it appeared |
| that this was a much smaller change to the standard that the other two |
| suggestions, and any efficiency concerns were more than offset by the |
| advantages of the solution. Two implementors reported that the |
| proposed resolution passed their test suites.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="182"></a>182. Ambiguous references to size_t</h3> |
| <p><b>Section:</b> 17 [library] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Al Stevens <b>Date:</b> 1999-08-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#library">issues</a> in [library].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Many references to <tt> size_t</tt> throughout the document |
| omit the <tt> std::</tt> namespace qualification.</p> <p>For |
| example, 17.4.3.5 [replacement.functions] paragraph 2:</p> |
| <blockquote> |
| <pre> operator new(size_t) |
| operator new(size_t, const std::nothrow_t&) |
| operator new[](size_t) |
| operator new[](size_t, const std::nothrow_t&)</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> In 17.4.3.5 [replacement.functions] paragraph 2: replace:</p> |
| <blockquote> |
| <p><tt> - operator new(size_t)<br> |
| - operator new(size_t, const std::nothrow_t&)<br> |
| - operator new[](size_t)<br> |
| - operator new[](size_t, const std::nothrow_t&)</tt></p> |
| </blockquote> |
| <p> by:</p> |
| <blockquote> |
| <pre>- operator new(std::size_t) |
| - operator new(std::size_t, const std::nothrow_t&) |
| - operator new[](std::size_t) |
| - operator new[](std::size_t, const std::nothrow_t&)</pre> |
| </blockquote> |
| <p>In [lib.allocator.requirements] 20.1.5, paragraph 4: replace:</p> |
| <blockquote> |
| <p>The typedef members pointer, const_pointer, size_type, and difference_type |
| are required to be T*, T const*, size_t, and ptrdiff_t, respectively.</p> |
| </blockquote> |
| <p> by:</p> |
| <blockquote> |
| <p>The typedef members pointer, const_pointer, size_type, and difference_type |
| are required to be T*, T const*, std::size_t, and std::ptrdiff_t, |
| respectively.</p> |
| </blockquote> |
| <p>In [lib.allocator.members] 20.4.1.1, paragraphs 3 and 6: replace:</p> |
| <blockquote> |
| <p>3 Notes: Uses ::operator new(size_t) (18.4.1).</p> |
| <p>6 Note: the storage is obtained by calling ::operator new(size_t), but it |
| is unspecified when or how often this function is called. The use of hint is |
| unspecified, but intended as an aid to locality if an implementation so |
| desires.</p> |
| </blockquote> |
| <p>by:</p> |
| <blockquote> |
| <p>3 Notes: Uses ::operator new(std::size_t) (18.4.1).</p> |
| <p>6 Note: the storage is obtained by calling ::operator new(std::size_t), but |
| it is unspecified when or how often this function is called. The use of hint |
| is unspecified, but intended as an aid to locality if an implementation so |
| desires.</p> |
| </blockquote> |
| <p>In [lib.char.traits.require] 21.1.1, paragraph 1: replace:</p> |
| <blockquote> |
| <p>In Table 37, X denotes a Traits class defining types and functions for the |
| character container type CharT; c and d denote values of type CharT; p and q |
| denote values of type const CharT*; s denotes a value of type CharT*; n, i and |
| j denote values of type size_t; e and f denote values of type X::int_type; pos |
| denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p> |
| </blockquote> |
| <p>by:</p> |
| <blockquote> |
| <p>In Table 37, X denotes a Traits class defining types and functions for the |
| character container type CharT; c and d denote values of type CharT; p and q |
| denote values of type const CharT*; s denotes a value of type CharT*; n, i and |
| j denote values of type std::size_t; e and f denote values of type X::int_type; |
| pos denotes a value of type X::pos_type; and state denotes a value of type X::state_type.</p> |
| </blockquote> |
| <p>In [lib.char.traits.require] 21.1.1, table 37: replace the return type of |
| X::length(p): "size_t" by "std::size_t".</p> |
| <p> In [lib.std.iterator.tags] 24.3.3, paragraph 2: replace:<br> |
| typedef ptrdiff_t difference_type;<br> |
| by:<br> |
| typedef std::ptrdiff_t difference_type;</p> |
| <p> In [lib.locale.ctype] 22.2.1.1 put namespace std { ...} around the |
| declaration of template <class charT> class ctype.<br> |
| <br> |
| In [lib.iterator.traits] 24.3.1, paragraph 2 put namespace std { ...} around the declaration of:<br> |
| <br> |
| template<class Iterator> struct iterator_traits<br> |
| template<class T> struct iterator_traits<T*><br> |
| template<class T> struct iterator_traits<const T*></p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes correcting names like <tt>size_t</tt> and |
| <tt>ptrdiff_t</tt> to <tt>std::size_t</tt> and <tt>std::ptrdiff_t</tt> |
| to be essentially editorial. There there can't be another size_t or |
| ptrdiff_t meant anyway because, according to 17.4.3.2.4 [extern.types],</p> |
| |
| <blockquote><p> |
| For each type T from the Standard C library, the types ::T and std::T |
| are reserved to the implementation and, when defined, ::T shall be |
| identical to std::T. |
| </p></blockquote> |
| |
| <p>The issue is treated as a Defect Report to make explicit the Project |
| Editor's authority to make this change.</p> |
| |
| <p><i>[Post-Tokyo: Nico Josuttis provided the above wording at the |
| request of the LWG.]</i></p> |
| |
| |
| <p><i>[Toronto: This is tangentially related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>, but only tangentially: the intent of this issue is to |
| address use of the name <tt>size_t</tt> in contexts outside of |
| namespace std, such as in the description of <tt>::operator new</tt>. |
| The proposed changes should be reviewed to make sure they are |
| correct.]</i></p> |
| |
| |
| <p><i>[pre-Copenhagen: Nico has reviewed the changes and believes |
| them to be correct.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="183"></a>183. I/O stream manipulators don't work for wide character streams</h3> |
| <p><b>Section:</b> 27.6.3 [std.manip] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andy Sawyer <b>Date:</b> 1999-07-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#std.manip">issues</a> in [std.manip].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.6.3 [std.manip] paragraph 3 says (clause numbering added for |
| exposition):</p> |
| <blockquote> |
| <p>Returns: An object s of unspecified type such that if [1] out is an (instance |
| of) basic_ostream then the expression out<<s behaves as if f(s) were |
| called, and if [2] in is an (instance of) basic_istream then the expression |
| in>>s behaves as if f(s) were called. Where f can be defined as: ios_base& |
| f(ios_base& str, ios_base::fmtflags mask) { // reset specified flags |
| str.setf(ios_base::fmtflags(0), mask); return str; } [3] The expression |
| out<<s has type ostream& and value out. [4] The expression in>>s |
| has type istream& and value in.</p> |
| </blockquote> |
| <p>Given the definitions [1] and [2] for out and in, surely [3] should read: |
| "The expression out << s has type basic_ostream& ..." and |
| [4] should read: "The expression in >> s has type basic_istream& |
| ..."</p> |
| <p>If the wording in the standard is correct, I can see no way of implementing |
| any of the manipulators so that they will work with wide character streams.</p> |
| <p>e.g. wcout << setbase( 16 );</p> |
| <p>Must have value 'wcout' (which makes sense) and type 'ostream&' (which |
| doesn't).</p> |
| <p>The same "cut'n'paste" type also seems to occur in Paras 4,5,7 and |
| 8. In addition, Para 6 [setfill] has a similar error, but relates only to |
| ostreams.</p> |
| <p>I'd be happier if there was a better way of saying this, to make it clear |
| that the value of the expression is "the same specialization of |
| basic_ostream as out"&</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace section 27.6.3 [std.manip] except paragraph 1 with the |
| following:</p> |
| <blockquote> |
| <p>2- The type designated smanip in each of the following function |
| descriptions is implementation-specified and may be different for each |
| function.<br> |
| <br> |
| <tt>smanip resetiosflags(ios_base::fmtflags mask);</tt><br> |
| <br> |
| -3- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, mask) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if |
| f(s, mask) were called. The function f can be defined as:*<br> |
| <br> |
| [Footnote: The expression cin >> resetiosflags(ios_base::skipws) |
| clears ios_base::skipws in the format flags stored in the |
| basic_istream<charT,traits> object cin (the same as cin >> |
| noskipws), and the expression cout << |
| resetiosflags(ios_base::showbase) clears |
| ios_base::showbase in the format flags stored in the |
| basic_ostream<charT,traits> object cout (the same as cout |
| << |
| noshowbase). --- end footnote]<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, ios_base::fmtflags mask)<br> |
| {<br> |
| // reset specified flags<br> |
| str.setf(ios_base::fmtflags(0), mask);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setiosflags(ios_base::fmtflags mask);</tt><br> |
| <br> |
| -4- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, mask) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, |
| mask) were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, ios_base::fmtflags mask)<br> |
| {<br> |
| // set specified flags<br> |
| str.setf(mask);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setbase(int base);</tt><br> |
| <br> |
| -5- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, base) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, |
| base) were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int base)<br> |
| {<br> |
| // set basefield<br> |
| str.setf(base == 8 ? ios_base::oct :<br> |
| base == 10 ? ios_base::dec :<br> |
| base == 16 ? ios_base::hex :<br> |
| ios_base::fmtflags(0), ios_base::basefield);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in.<br> |
| <br> |
| <tt>smanip setfill(char_type c);<br> |
| </tt><br> |
| -6- Returns: An object s of unspecified type such that if out is (or is |
| derived from) basic_ostream<charT,traits> and c has type charT |
| then the |
| expression out<<s behaves as if f(s, c) were called. The function |
| f can be |
| defined as:<br> |
| <br> |
| <tt>template<class charT, class traits><br> |
| basic_ios<charT,traits>& f(basic_ios<charT,traits>& str, charT c)<br> |
| {<br> |
| // set fill character<br> |
| str.fill(c);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out.<br> |
| <br> |
| <tt>smanip setprecision(int n);</tt><br> |
| <br> |
| -7- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, n) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, n) |
| were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int n)<br> |
| {<br> |
| // set precision<br> |
| str.precision(n);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type basic_ostream<charT,traits>& and value out. |
| The expression in>>s has type basic_istream<charT,traits>& and value in<br> |
| .<br> |
| <tt>smanip setw(int n);<br> |
| </tt><br> |
| -8- Returns: An object s of unspecified type such that if out is an |
| instance of basic_ostream<charT,traits> then the expression |
| out<<s behaves |
| as if f(s, n) were called, or if in is an instance of |
| basic_istream<charT,traits> then the expression in>>s |
| behaves as if f(s, n) |
| were called. The function f can be defined as:<br> |
| <br> |
| <tt>ios_base& f(ios_base& str, int n)<br> |
| {<br> |
| // set width<br> |
| str.width(n);<br> |
| return str;<br> |
| }<br> |
| </tt><br> |
| The expression out<<s has type |
| basic_ostream<charT,traits>& and value out. The expression |
| in>>s has type basic_istream<charT,traits>& and value |
| in. |
| </p> |
| </blockquote> |
| |
| <p><i>[Kona: Andy Sawyer and Beman Dawes will work to improve the wording of |
| the proposed resolution.]</i></p> |
| |
| |
| <p><i>[Tokyo - The LWG noted that issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#216">216</a> involves |
| the same paragraphs.]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: The issues list maintainer combined the proposed |
| resolution of this issue with the proposed resolution for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#216">216</a> as they both involved the same paragraphs, and were so |
| intertwined that dealing with them separately appear fraught with |
| error. The full text was supplied by Bill Plauger; it was cross |
| checked against changes supplied by Andy Sawyer. It should be further |
| checked by the LWG.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="184"></a>184. numeric_limits<bool> wording problems</h3> |
| <p><b>Section:</b> 18.2.1.5 [numeric.special] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 1999-07-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#numeric.special">issues</a> in [numeric.special].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>bools are defined by the standard to be of integer types, as per |
| 3.9.1 [basic.fundamental] paragraph 7. However "integer types" |
| seems to have a special meaning for the author of 18.2. The net effect |
| is an unclear and confusing specification for |
| numeric_limits<bool> as evidenced below.</p> |
| |
| <p>18.2.1.2/7 says numeric_limits<>::digits is, for built-in integer |
| types, the number of non-sign bits in the representation.</p> |
| |
| <p>4.5/4 states that a bool promotes to int ; whereas 4.12/1 says any non zero |
| arithmetical value converts to true.</p> |
| |
| <p>I don't think it makes sense at all to require |
| numeric_limits<bool>::digits and numeric_limits<bool>::digits10 to |
| be meaningful.</p> |
| |
| <p>The standard defines what constitutes a signed (resp. unsigned) integer |
| types. It doesn't categorize bool as being signed or unsigned. And the set of |
| values of bool type has only two elements.</p> |
| |
| <p>I don't think it makes sense to require numeric_limits<bool>::is_signed |
| to be meaningful.</p> |
| |
| <p>18.2.1.2/18 for numeric_limits<integer_type>::radix says:</p> |
| <blockquote> |
| <p>For integer types, specifies the base of the representation.186)</p> |
| </blockquote> |
| |
| <p>This disposition is at best misleading and confusing for the standard |
| requires a "pure binary numeration system" for integer types as per |
| 3.9.1/7</p> |
| |
| <p>The footnote 186) says: "Distinguishes types with base other than 2 (e.g |
| BCD)." This also erroneous as the standard never defines any integer |
| types with base representation other than 2.</p> |
| |
| <p>Furthermore, numeric_limits<bool>::is_modulo and |
| numeric_limits<bool>::is_signed have similar problems.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Append to the end of 18.2.1.5 [numeric.special]:</p> |
| <blockquote> |
| <p>The specialization for bool shall be provided as follows:</p> |
| <pre> namespace std { |
| template<> class numeric_limits<bool> { |
| public: |
| static const bool is_specialized = true; |
| static bool min() throw() { return false; } |
| static bool max() throw() { return true; } |
| |
| static const int digits = 1; |
| static const int digits10 = 0; |
| static const bool is_signed = false; |
| static const bool is_integer = true; |
| static const bool is_exact = true; |
| static const int radix = 2; |
| static bool epsilon() throw() { return 0; } |
| static bool round_error() throw() { return 0; } |
| |
| static const int min_exponent = 0; |
| static const int min_exponent10 = 0; |
| static const int max_exponent = 0; |
| static const int max_exponent10 = 0; |
| |
| static const bool has_infinity = false; |
| static const bool has_quiet_NaN = false; |
| static const bool has_signaling_NaN = false; |
| static const float_denorm_style has_denorm = denorm_absent; |
| static const bool has_denorm_loss = false; |
| static bool infinity() throw() { return 0; } |
| static bool quiet_NaN() throw() { return 0; } |
| static bool signaling_NaN() throw() { return 0; } |
| static bool denorm_min() throw() { return 0; } |
| |
| static const bool is_iec559 = false; |
| static const bool is_bounded = true; |
| static const bool is_modulo = false; |
| |
| static const bool traps = false; |
| static const bool tinyness_before = false; |
| static const float_round_style round_style = round_toward_zero; |
| }; |
| }</pre> |
| </blockquote> |
| |
| <p><i>[Tokyo: The LWG desires wording that specifies exact values |
| rather than more general wording in the original proposed |
| resolution.]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: At the request of the LWG in Tokyo, Nico |
| Josuttis provided the above wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="185"></a>185. Questionable use of term "inline"</h3> |
| <p><b>Section:</b> 20.6 [function.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> UK Panel <b>Date:</b> 1999-07-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#function.objects">issues</a> in [function.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 4 of 20.6 [function.objects] says:</p> |
| <blockquote> |
| <p> [Example: To negate every element of a: transform(a.begin(), a.end(), |
| a.begin(), negate<double>()); The corresponding functions will inline |
| the addition and the negation. end example]</p> |
| </blockquote> |
| <p>(Note: The "addition" referred to in the above is in para 3) we can |
| find no other wording, except this (non-normative) example which suggests that |
| any "inlining" will take place in this case.</p> |
| <p>Indeed both:</p> |
| <blockquote> |
| <p>17.4.4.3 Global Functions [lib.global.functions] 1 It is |
| unspecified whether any global functions in the C++ Standard Library |
| are defined as inline (7.1.2).</p> |
| </blockquote> |
| <p>and</p> |
| <blockquote> |
| <p>17.4.4.4 Member Functions [lib.member.functions] 1 It is |
| unspecified whether any member functions in the C++ Standard Library |
| are defined as inline (7.1.2).</p> |
| </blockquote> |
| <p>take care to state that this may indeed NOT be the case.</p> |
| <p>Thus the example "mandates" behavior that is explicitly |
| not required elsewhere.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 20.6 [function.objects] paragraph 1, remove the sentence:</p> |
| <blockquote> |
| <p>They are important for the effective use of the library.</p> |
| </blockquote> |
| <p>Remove 20.6 [function.objects] paragraph 2, which reads:</p> |
| <blockquote> |
| <p> Using function objects together with function templates |
| increases the expressive power of the library as well as making the |
| resulting code much more efficient.</p> |
| </blockquote> |
| <p>In 20.6 [function.objects] paragraph 4, remove the sentence:</p> |
| <blockquote> |
| <p>The corresponding functions will inline the addition and the |
| negation.</p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG agreed there was a defect.]</i></p> |
| |
| <p><i>[Tokyo: The LWG crafted the proposed resolution.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="186"></a>186. bitset::set() second parameter should be bool</h3> |
| <p><b>Section:</b> 23.3.5.2 [bitset.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Darin Adler <b>Date:</b> 1999-08-13</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#bitset.members">issues</a> in [bitset.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In section 23.3.5.2 [bitset.members], paragraph 13 defines the |
| bitset::set operation to take a second parameter of type int. The |
| function tests whether this value is non-zero to determine whether to |
| set the bit to true or false. The type of this second parameter should |
| be bool. For one thing, the intent is to specify a Boolean value. For |
| another, the result type from test() is bool. In addition, it's |
| possible to slice an integer that's larger than an int. This can't |
| happen with bool, since conversion to bool has the semantic of |
| translating 0 to false and any non-zero value to true.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.3.5 [template.bitset] Para 1 Replace:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, int val = true ); </pre> |
| </blockquote> |
| <p>With:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, bool val = true );</pre> |
| </blockquote> |
| <p>In 23.3.5.2 [bitset.members] Para 12(.5) Replace:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, int val = 1 );</pre> |
| </blockquote> |
| <p>With:</p> |
| <blockquote> |
| <pre>bitset<N>& set(size_t pos, bool val = true );</pre> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG agrees with the description. Andy Sawyer will work |
| on better P/R wording.]</i></p> |
| |
| <p><i>[Post-Tokyo: Andy provided the above wording.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p><tt>bool</tt> is a better choice. It is believed that binary |
| compatibility is not an issue, because this member function is |
| usually implemented as <tt>inline</tt>, and because it is already |
| the case that users cannot rely on the type of a pointer to a |
| nonvirtual member of a standard library class.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="187"></a>187. iter_swap underspecified</h3> |
| <p><b>Section:</b> 25.2.3 [alg.swap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1999-08-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.swap">issues</a> in [alg.swap].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description of iter_swap in 25.2.2 paragraph 7,says that it |
| ``exchanges the values'' of the objects to which two iterators |
| refer.<br> <br> What it doesn't say is whether it does so using swap |
| or using the assignment operator and copy constructor.<br> <br> This |
| question is an important one to answer, because swap is specialized to |
| work efficiently for standard containers.<br> For example:</p> |
| <blockquote> |
| <pre>vector<int> v1, v2; |
| iter_swap(&v1, &v2);</pre> |
| </blockquote> |
| <p>Is this call to iter_swap equivalent to calling swap(v1, v2)? |
| Or is it equivalent to</p> |
| <blockquote> |
| <pre>{ |
| vector<int> temp = v1; |
| v1 = v2; |
| v2 = temp; |
| }</pre> |
| </blockquote> |
| <p>The first alternative is O(1); the second is O(n).</p> |
| <p>A LWG member, Dave Abrahams, comments:</p> |
| <blockquote> |
| <p>Not an objection necessarily, but I want to point out the cost of |
| that requirement:</p> |
| <blockquote> |
| <p><tt>iter_swap(list<T>::iterator, list<T>::iterator)</tt></p> |
| </blockquote> |
| <p>can currently be specialized to be more efficient than |
| iter_swap(T*,T*) for many T (by using splicing). Your proposal would |
| make that optimization illegal. </p> |
| </blockquote> |
| |
| <p><i>[Kona: The LWG notes the original need for iter_swap was proxy iterators |
| which are no longer permitted.]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the effect clause of iter_swap in 25.2.2 paragraph 7 from:</p> |
| <blockquote> |
| <p>Exchanges the values pointed to by the two iterators a and b.</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p><tt>swap(*a, *b)</tt>.</p> |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>It's useful to say just what <tt>iter_swap</tt> does. There may be |
| some iterators for which we want to specialize <tt>iter_swap</tt>, |
| but the fully general version should have a general specification.</p> |
| |
| <p>Note that in the specific case of <tt>list<T>::iterator</tt>, |
| iter_swap should not be specialized as suggested above. That would do |
| much more than exchanging the two iterators' values: it would change |
| predecessor/successor relationships, possibly moving the iterator from |
| one list to another. That would surely be inappropriate.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="189"></a>189. setprecision() not specified correctly</h3> |
| <p><b>Section:</b> 27.4.2.2 [fmtflags.state] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 1999-08-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#fmtflags.state">issues</a> in [fmtflags.state].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.4.2.2 paragraph 9 claims that setprecision() sets the precision, |
| and includes a parenthetical note saying that it is the number of |
| digits after the decimal point.<br> |
| <br> |
| This claim is not strictly correct. For example, in the default |
| floating-point output format, setprecision sets the number of |
| significant digits printed, not the number of digits after the decimal |
| point.<br> |
| <br> |
| I would like the committee to look at the definition carefully and |
| correct the statement in 27.4.2.2</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove from 27.4.2.2 [fmtflags.state], paragraph 9, the text |
| "(number of digits after the decimal point)".</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="193"></a>193. Heap operations description incorrect</h3> |
| <p><b>Section:</b> 25.3.6 [alg.heap.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Markus Mauhart <b>Date:</b> 1999-09-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#216">216</a></p> |
| <p><b>Discussion:</b></p> |
| <p>25.3.6 [lib.alg.heap.operations] states two key properties of a heap [a,b), the first of them |
| is<br> |
| <br> |
| `"(1) *a is the largest element"<br> |
| <br> |
| I think this is incorrect and should be changed to the wording in the proposed |
| resolution.</p> |
| <p>Actually there are two independent changes:</p> |
| <blockquote> |
| <p>A-"part of largest equivalence class" instead of "largest", cause 25.3 |
| [lib.alg.sorting] asserts "strict weak ordering" for all its sub clauses.</p> |
| <p>B-Take |
| 'an oldest' from that equivalence class, otherwise the heap functions |
| could not be used for a priority queue as explained in 23.2.3.2.2 |
| [lib.priqueue.members] (where I assume that a "priority queue" respects |
| priority AND time).</p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.3.6 [alg.heap.operations] property (1) from:</p> |
| <blockquote> |
| <p>(1) *a is the largest element</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>(1) There is no element greater than <tt>*a</tt></p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="195"></a>195. Should <tt>basic_istream::sentry</tt>'s constructor ever set eofbit?</h3> |
| <p><b>Section:</b> 27.6.1.1.3 [istream::sentry] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1999-10-13</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::sentry">issues</a> in [istream::sentry].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Suppose that <tt>is.flags() & ios_base::skipws</tt> is nonzero. |
| What should <tt>basic_istream<>::sentry</tt>'s constructor do if it |
| reaches eof while skipping whitespace? 27.6.1.1.2/5 suggests it |
| should set failbit. Should it set eofbit as well? The standard |
| doesn't seem to answer that question.</p> |
| |
| <p>On the one hand, nothing in 27.6.1.1.3 [istream::sentry] says that |
| <tt>basic_istream<>::sentry</tt> should ever set eofbit. On the |
| other hand, 27.6.1.1 [istream] paragraph 4 says that if |
| extraction from a <tt>streambuf</tt> "returns |
| <tt>traits::eof()</tt>, then the input function, except as explicitly |
| noted otherwise, completes its actions and does |
| <tt>setstate(eofbit)"</tt>. So the question comes down to |
| whether <tt>basic_istream<>::sentry</tt>'s constructor is an |
| input function.</p> |
| |
| <p>Comments from Jerry Schwarz:</p> |
| <blockquote> |
| <p>It was always my intention that eofbit should be set any time that a |
| virtual returned something to indicate eof, no matter what reason |
| iostream code had for calling the virtual.</p> |
| <p> |
| The motivation for this is that I did not want to require streambufs |
| to behave consistently if their virtuals are called after they have |
| signaled eof.</p> |
| <p> |
| The classic case is a streambuf reading from a UNIX file. EOF isn't |
| really a state for UNIX file descriptors. The convention is that a |
| read on UNIX returns 0 bytes to indicate "EOF", but the file |
| descriptor isn't shut down in any way and future reads do not |
| necessarily also return 0 bytes. In particular, you can read from |
| tty's on UNIX even after they have signaled "EOF". (It |
| isn't always understood that a ^D on UNIX is not an EOF indicator, but |
| an EOL indicator. By typing a "line" consisting solely of |
| ^D you cause a read to return 0 bytes, and by convention this is |
| interpreted as end of file.)</p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a sentence to the end of 27.6.1.1.2 paragraph 2:</p> |
| <blockquote> |
| <p>If <tt>is.rdbuf()->sbumpc()</tt> or <tt>is.rdbuf()->sgetc()</tt> |
| returns <tt>traits::eof()</tt>, the function calls |
| <tt>setstate(failbit | eofbit)</tt> (which may throw |
| <tt>ios_base::failure</tt>). |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="198"></a>198. Validity of pointers and references unspecified after iterator destruction</h3> |
| <p><b>Section:</b> 24.1 [iterator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 1999-11-03</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#iterator.requirements">active issues</a> in [iterator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iterator.requirements">issues</a> in [iterator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Is a pointer or reference obtained from an iterator still valid after |
| destruction of the iterator? |
| </p> |
| <p> |
| Is a pointer or reference obtained from an iterator still valid after the value |
| of the iterator changes? |
| </p> |
| <blockquote> |
| <pre>#include <iostream> |
| #include <vector> |
| #include <iterator> |
| |
| int main() |
| { |
| typedef std::vector<int> vec_t; |
| vec_t v; |
| v.push_back( 1 ); |
| |
| // Is a pointer or reference obtained from an iterator still |
| // valid after destruction of the iterator? |
| int * p = &*v.begin(); |
| std::cout << *p << '\n'; // OK? |
| |
| // Is a pointer or reference obtained from an iterator still |
| // valid after the value of the iterator changes? |
| vec_t::iterator iter( v.begin() ); |
| p = &*iter++; |
| std::cout << *p << '\n'; // OK? |
| |
| return 0; |
| } |
| </pre> |
| </blockquote> |
| |
| <p>The standard doesn't appear to directly address these |
| questions. The standard needs to be clarified. At least two real-world |
| cases have been reported where library implementors wasted |
| considerable effort because of the lack of clarity in the |
| standard. The question is important because requiring pointers and |
| references to remain valid has the effect for practical purposes of |
| prohibiting iterators from pointing to cached rather than actual |
| elements of containers.</p> |
| |
| <p>The standard itself assumes that pointers and references obtained |
| from an iterator are still valid after iterator destruction or |
| change. The definition of reverse_iterator::operator*(), 24.4.1.3.3 [reverse.iter.conv], which returns a reference, defines |
| effects:</p> |
| |
| <blockquote> |
| <pre>Iterator tmp = current; |
| return *--tmp;</pre> |
| </blockquote> |
| <p>The definition of reverse_iterator::operator->(), 24.4.1.3.4 |
| [reverse.iter.op.star], which returns a pointer, defines effects:</p> |
| <blockquote> |
| <pre>return &(operator*());</pre> |
| </blockquote> |
| |
| <p>Because the standard itself assumes pointers and references remain |
| valid after iterator destruction or change, the standard should say so |
| explicitly. This will also reduce the chance of user code breaking |
| unexpectedly when porting to a different standard library |
| implementation.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph to 24.1 [iterator.requirements]:</p> |
| <blockquote><p> |
| Destruction of an iterator may invalidate pointers and references |
| previously obtained from that iterator. |
| </p></blockquote> |
| |
| <p>Replace paragraph 1 of 24.4.1.3.3 [reverse.iter.conv] with:</p> |
| |
| <blockquote> |
| <p><b>Effects:</b></p> |
| <pre> this->tmp = current; |
| --this->tmp; |
| return *this->tmp; |
| </pre> |
| |
| <p> |
| [<i>Note:</i> This operation must use an auxiliary member variable, |
| rather than a temporary variable, to avoid returning a reference that |
| persists beyond the lifetime of its associated iterator. (See |
| 24.1 [iterator.requirements].) The name of this member variable is shown for |
| exposition only. <i>--end note</i>] |
| </p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: The issue has been reformulated purely |
| in terms of iterators.]</i></p> |
| |
| |
| <p><i>[Pre-Toronto: Steve Cleary pointed out the no-invalidation |
| assumption by reverse_iterator. The issue and proposed resolution was |
| reformulated yet again to reflect this reality.]</i></p> |
| |
| |
| <p><i>[Copenhagen: Steve Cleary pointed out that reverse_iterator |
| assumes its underlying iterator has persistent pointers and |
| references. Andy Koenig pointed out that it is possible to rewrite |
| reverse_iterator so that it no longer makes such an assupmption. |
| However, this issue is related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a>. If we |
| decide it is intentional that <tt>p[n]</tt> may return by value |
| instead of reference when <tt>p</tt> is a Random Access Iterator, |
| other changes in reverse_iterator will be necessary.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This issue has been discussed extensively. Note that it is |
| <i>not</i> an issue about the behavior of predefined iterators. It is |
| asking whether or not user-defined iterators are permitted to have |
| transient pointers and references. Several people presented examples |
| of useful user-defined iterators that have such a property; examples |
| include a B-tree iterator, and an "iota iterator" that doesn't point |
| to memory. Library implementors already seem to be able to cope with |
| such iterators: they take pains to avoid forming references to memory |
| that gets iterated past. The only place where this is a problem is |
| <tt>reverse_iterator</tt>, so this issue changes |
| <tt>reverse_iterator</tt> to make it work.</p> |
| |
| <p>This resolution does not weaken any guarantees provided by |
| predefined iterators like <tt>list<int>::iterator</tt>. |
| Clause 23 should be reviewed to make sure that guarantees for |
| predefined iterators are as strong as users expect.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="199"></a>199. What does <tt>allocate(0)</tt> return?</h3> |
| <p><b>Section:</b> 20.1.2 [allocator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1999-11-19</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Suppose that <tt>A</tt> is a class that conforms to the |
| Allocator requirements of Table 32, and <tt>a</tt> is an |
| object of class <tt>A</tt> What should be the return |
| value of <tt>a.allocate(0)</tt>? Three reasonable |
| possibilities: forbid the argument <tt>0</tt>, return |
| a null pointer, or require that the return value be a |
| unique non-null pointer. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a note to the <tt>allocate</tt> row of Table 32: |
| "[<i>Note:</i> If <tt>n == 0</tt>, the return value is unspecified. <i>--end note</i>]"</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>A key to understanding this issue is that the ultimate use of |
| allocate() is to construct an iterator, and that iterator for zero |
| length sequences must be the container's past-the-end |
| representation. Since this already implies special case code, it |
| would be over-specification to mandate the return value. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="200"></a>200. Forward iterator requirements don't allow constant iterators</h3> |
| <p><b>Section:</b> 24.1.3 [forward.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 1999-11-19</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#forward.iterators">issues</a> in [forward.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In table 74, the return type of the expression <tt>*a</tt> is given |
| as <tt>T&</tt>, where <tt>T</tt> is the iterator's value type. |
| For constant iterators, however, this is wrong. ("Value type" |
| is never defined very precisely, but it is clear that the value type |
| of, say, <tt>std::list<int>::const_iterator</tt> is supposed to be |
| <tt>int</tt>, not <tt>const int</tt>.) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In table 74, in the <tt>*a</tt> and <tt>*r++</tt> rows, change the |
| return type from "<tt>T&</tt>" to "<tt>T&</tt> |
| if <tt>X</tt> is mutable, otherwise <tt>const T&</tt>". |
| In the <tt>a->m</tt> row, change the return type from |
| "<tt>U&</tt>" to "<tt>U&</tt> if <tt>X</tt> is mutable, |
| otherwise <tt>const U&</tt>". |
| </p> |
| |
| <p><i>[Tokyo: The LWG believes this is the tip of a larger iceberg; |
| there are multiple const problems with the STL portion of the library |
| and that these should be addressed as a single package. Note |
| that issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#180">180</a> has already been declared NAD Future for |
| that very reason.]</i></p> |
| |
| |
| <p><i>[Redmond: the LWG thinks this is separable from other constness |
| issues. This issue is just cleanup; it clarifies language that was |
| written before we had iterator_traits. Proposed resolution was |
| modified: the original version only discussed *a. It was pointed out |
| that we also need to worry about *r++ and a->m.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="201"></a>201. Numeric limits terminology wrong</h3> |
| <p><b>Section:</b> 18.2.1 [limits] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Stephen Cleary <b>Date:</b> 1999-12-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#limits">issues</a> in [limits].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In some places in this section, the terms "fundamental types" and |
| "scalar types" are used when the term "arithmetic types" is intended. |
| The current usage is incorrect because void is a fundamental type and |
| pointers are scalar types, neither of which should have |
| specializations of numeric_limits. |
| </p> |
| <p><i>[Lillehammer: it remains true that numeric_limits is using |
| imprecise language. However, none of the proposals for changed |
| wording are clearer. A redesign of numeric_limits is needed, but this |
| is more a task than an open issue.]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change 18.2 [support.limits] to: |
| </p> |
| |
| <blockquote> |
| <p> |
| -1- The headers <tt><limits></tt>, <tt><climits></tt>, |
| <tt><cfloat></tt>, and <tt><cinttypes></tt> supply |
| characteristics of implementation-dependent <del>fundamental</del> |
| <ins>arithmetic</ins> types (3.9.1). |
| </p> |
| </blockquote> |
| |
| <p> |
| Change 18.2.1 [limits] to: |
| </p> |
| |
| <blockquote> |
| <p> |
| -1- The <tt>numeric_limits</tt> component provides a C++ program with |
| information about various properties of the implementation's |
| representation of the <del>fundamental</del> <ins>arithmetic</ins> |
| types. |
| </p> |
| <p> |
| -2- Specializations shall be provided for each <del>fundamental</del> |
| <ins>arithmetic</ins> type, both floating point and integer, including |
| <tt>bool</tt>. The member <tt>is_specialized</tt> shall be <tt>true</tt> |
| for all such specializations of <tt>numeric_limits</tt>. |
| </p> |
| <p> |
| -4- Non-<del>fundamental</del><ins>arithmetic</ins> standard types, such |
| as <tt>complex<T></tt> (26.3.2), shall not have specializations. |
| </p> |
| </blockquote> |
| |
| <p> |
| Change 18.2.1.1 [numeric.limits] to: |
| </p> |
| |
| <blockquote> |
| <p> |
| <del>-1- The member <tt>is_specialized</tt> makes it possible to distinguish |
| between fundamental types, which have specializations, and non-scalar types, |
| which do not.</del> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="202"></a>202. unique() effects unclear when predicate not an equivalence relation</h3> |
| <p><b>Section:</b> 25.2.9 [alg.unique] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 2000-01-13</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.unique">issues</a> in [alg.unique].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| What should unique() do if you give it a predicate that is not an |
| equivalence relation? There are at least two plausible answers: |
| </p> |
| |
| <blockquote> |
| |
| <p> |
| 1. You can't, because 25.2.8 says that it it "eliminates all but |
| the first element from every consecutive group of equal |
| elements..." and it wouldn't make sense to interpret "equal" as |
| meaning anything but an equivalence relation. [It also doesn't |
| make sense to interpret "equal" as meaning ==, because then there |
| would never be any sense in giving a predicate as an argument at |
| all.] |
| </p> |
| |
| <p> |
| 2. The word "equal" should be interpreted to mean whatever the |
| predicate says, even if it is not an equivalence relation |
| (and in particular, even if it is not transitive). |
| </p> |
| |
| </blockquote> |
| |
| <p> |
| The example that raised this question is from Usenet: |
| </p> |
| |
| <blockquote> |
| |
| <pre>int f[] = { 1, 3, 7, 1, 2 }; |
| int* z = unique(f, f+5, greater<int>());</pre> |
| |
| </blockquote> |
| |
| <p> |
| If one blindly applies the definition using the predicate |
| greater<int>, and ignore the word "equal", you get: |
| </p> |
| |
| <blockquote> |
| |
| <p> |
| Eliminates all but the first element from every consecutive group |
| of elements referred to by the iterator i in the range [first, last) |
| for which *i > *(i - 1). |
| </p> |
| |
| </blockquote> |
| |
| <p> |
| The first surprise is the order of the comparison. If we wanted to |
| allow for the predicate not being an equivalence relation, then we |
| should surely compare elements the other way: pred(*(i - 1), *i). If |
| we do that, then the description would seem to say: "Break the |
| sequence into subsequences whose elements are in strictly increasing |
| order, and keep only the first element of each subsequence". So the |
| result would be 1, 1, 2. If we take the description at its word, it |
| would seem to call for strictly DEcreasing order, in which case the |
| result should be 1, 3, 7, 2.<br> |
| <br> |
| In fact, the SGI implementation of unique() does neither: It yields 1, |
| 3, 7. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.2.9 [alg.unique] paragraph 1 to:</p> |
| <blockquote><p> |
| For a nonempty range, eliminates all but the first element from every |
| consecutive group of equivalent elements referred to by the iterator |
| <tt>i</tt> in the range [first+1, last) for which the following |
| conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) != |
| false</tt>. |
| </p></blockquote> |
| |
| <p> |
| Also insert a new paragraph, paragraph 2a, that reads: "Requires: The |
| comparison function must be an equivalence relation." |
| </p> |
| |
| <p><i>[Redmond: discussed arguments for and against requiring the |
| comparison function to be an equivalence relation. Straw poll: |
| 14-2-5. First number is to require that it be an equivalence |
| relation, second number is to explicitly not require that it be an |
| equivalence relation, third number is people who believe they need |
| more time to consider the issue. A separate issue: Andy Sawyer |
| pointed out that "i-1" is incorrect, since "i" can refer to the first |
| iterator in the range. Matt provided wording to address this |
| problem.]</i></p> |
| |
| |
| <p><i>[Curaçao: The LWG changed "... the range (first, |
| last)..." to "... the range [first+1, last)..." for |
| clarity. They considered this change close enough to editorial to not |
| require another round of review.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG also considered an alternative resolution: change |
| 25.2.9 [alg.unique] paragraph 1 to:</p> |
| |
| <blockquote><p> |
| For a nonempty range, eliminates all but the first element from every |
| consecutive group of elements referred to by the iterator |
| <tt>i</tt> in the range (first, last) for which the following |
| conditions hold: <tt>*(i-1) == *i</tt> or <tt>pred(*(i-1), *i) != |
| false</tt>. |
| </p></blockquote> |
| |
| <p> |
| Also insert a new paragraph, paragraph 1a, that reads: "Notes: The |
| comparison function need not be an equivalence relation." |
| </p> |
| |
| |
| <p>Informally: the proposed resolution imposes an explicit requirement |
| that the comparison function be an equivalence relation. The |
| alternative resolution does not, and it gives enough information so |
| that the behavior of unique() for a non-equivalence relation is |
| specified. Both resolutions are consistent with the behavior of |
| existing implementations.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="206"></a>206. operator new(size_t, nothrow) may become unlinked to ordinary operator new if ordinary version replaced</h3> |
| <p><b>Section:</b> 18.5.1.1 [new.delete.single] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 1999-08-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#new.delete.single">issues</a> in [new.delete.single].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>As specified, the implementation of the nothrow version of operator |
| new does not necessarily call the ordinary operator new, but may |
| instead simply call the same underlying allocator and return a null |
| pointer instead of throwing an exception in case of failure.</p> |
| |
| <p>Such an implementation breaks code that replaces the ordinary |
| version of new, but not the nothrow version. If the ordinary version |
| of new/delete is replaced, and if the replaced delete is not |
| compatible with pointers returned from the library versions of new, |
| then when the replaced delete receives a pointer allocated by the |
| library new(nothrow), crash follows.</p> |
| |
| <p>The fix appears to be that the lib version of new(nothrow) must |
| call the ordinary new. Thus when the ordinary new gets replaced, the |
| lib version will call the replaced ordinary new and things will |
| continue to work.</p> |
| |
| <p>An alternative would be to have the ordinary new call |
| new(nothrow). This seems sub-optimal to me as the ordinary version of |
| new is the version most commonly replaced in practice. So one would |
| still need to replace both ordinary and nothrow versions if one wanted |
| to replace the ordinary version.</p> |
| |
| <p>Another alternative is to put in clear text that if one version is |
| replaced, then the other must also be replaced to maintain |
| compatibility. Then the proposed resolution below would just be a |
| quality of implementation issue. There is already such text in |
| paragraph 7 (under the new(nothrow) version). But this nuance is |
| easily missed if one reads only the paragraphs relating to the |
| ordinary new.</p> |
| |
| <p> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2158.html">N2158</a> |
| has been written explaining the rationale for the proposed resolution below. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 18.5.1.1 [new.delete.single]: |
| </p> |
| |
| <blockquote> |
| <pre>void* operator new(std::size_t <i>size</i>, const std::nothrow_t&) throw(); |
| </pre> |
| <blockquote> |
| <p> |
| -5- <i>Effects:</i> Same as above, except that it is called by a placement |
| version of a <i>new-expression</i> when a C++ program prefers a null pointer result as |
| an error indication, instead of a <tt>bad_alloc</tt> exception. |
| </p> |
| |
| <p> |
| -6- <i>Replaceable:</i> a C++ program may define a function with this function |
| signature that displaces the default version defined by the C++ Standard |
| library. |
| </p> |
| |
| <p> |
| -7- <i>Required behavior:</i> Return a non-null pointer to suitably aligned |
| storage (3.7.4), or else return a null pointer. This nothrow version of operator |
| new returns a pointer obtained as if acquired from the <ins>(possibly |
| replaced)</ins> ordinary version. This requirement is binding on a replacement |
| version of this function. |
| </p> |
| |
| <p> |
| -8- <i>Default behavior:</i> |
| </p> |
| <ul> |
| <li><ins> |
| Calls <tt>operator new(<i>size</i>)</tt>. |
| </ins></li> |
| <li><ins> |
| If the call to <tt>operator new(<i>size</i>)</tt> returns normally, returns |
| the result of that call, else |
| </ins></li> |
| <li><ins> |
| if the call to <tt>operator new(<i>size</i>)</tt> throws an exception, returns |
| a null pointer. |
| </ins></li> |
| <li><del> |
| Executes a loop: Within the loop, the function first attempts to allocate the |
| requested storage. Whether the attempt involves a call to the Standard C library |
| function <tt>malloc</tt> is unspecified. |
| </del></li> |
| <li><del> |
| Returns a pointer to the allocated storage if the attempt is successful. |
| Otherwise, if the last argument to <tt>set_new_handler()</tt> was a null |
| pointer, return a null pointer. |
| </del></li> |
| <li><del> |
| Otherwise, the function calls the current <i>new_handler</i> (18.5.2.2). If the |
| called function returns, the loop repeats. |
| </del></li> |
| <li><del> |
| The loop terminates when an attempt to allocate the requested storage is |
| successful or when a called <i>new_handler</i> function does not return. If the |
| called <i>new_handler</i> function terminates by throwing a <tt>bad_alloc |
| exception</tt>, the function returns a null pointer. |
| </del></li> |
| </ul> |
| <p> |
| -9- [<i>Example:</i> |
| </p> |
| <blockquote><pre>T* p1 = new T; <i>// throws bad_alloc if it fails</i> |
| T* p2 = new(nothrow) T; <i>// returns 0 if it fails</i> |
| </pre></blockquote> |
| <p> |
| --<i>end example</i>] |
| </p> |
| </blockquote> |
| |
| <pre>void operator delete(void* <i>ptr</i>) throw(); |
| <del>void operator delete(void* <i>ptr</i>, const std::nothrow_t&) throw();</del> |
| </pre> |
| |
| <blockquote> |
| <p> |
| -10- <i>Effects:</i> The <i>deallocation function</i> (3.7.4.2) called by a |
| <i>delete-expression</i> to render the value of <tt><i>ptr</i></tt> invalid. |
| </p> |
| <p> |
| -11- <i>Replaceable:</i> a C++ program may define a function with this function |
| signature that displaces the default version defined by the C++ Standard |
| library. |
| </p> |
| <p> |
| -12- <i>Requires:</i> the value of <tt><i>ptr</i></tt> is null or the value |
| returned by an earlier call to the <del>default</del> <ins>(possibly |
| replaced)</ins> <tt>operator new(std::size_t)</tt> or <tt>operator |
| new(std::size_t, const std::nothrow_t&)</tt>. |
| </p> |
| <p> |
| -13- <i>Default behavior:</i> |
| </p> |
| <ul> |
| <li> |
| For a null value of <tt><i>ptr</i></tt>, do nothing. |
| </li> |
| <li> |
| Any other value of <tt><i>ptr</i></tt> shall be a value returned earlier by a |
| call to the default <tt>operator new</tt>, which was not invalidated by an |
| intervening call to <tt>operator delete(void*)</tt> (17.4.3.7). For such a |
| non-null value of <tt><i>ptr</i></tt>, reclaims storage allocated by the earlier |
| call to the default <tt>operator new</tt>. |
| </li> |
| </ul> |
| <p> |
| -14- <i>Remarks:</i> It is unspecified under what conditions part or all of |
| such reclaimed storage is allocated by a subsequent call to <tt>operator |
| new</tt> or any of <tt>calloc</tt>, <tt>malloc</tt>, or <tt>realloc</tt>, |
| declared in <tt><cstdlib></tt>. |
| </p> |
| </blockquote> |
| |
| <pre><ins>void operator delete(void* <i>ptr</i>, const std::nothrow_t&) throw();</ins> |
| </pre> |
| |
| <blockquote> |
| <p><ins> |
| -15- <i>Effects:</i> Same as above, except that it is called by the |
| implementation when an exception propagates from a nothrow placement version |
| of the <i>new-expression</i> (i.e. when the constructor throws an exception). |
| </ins></p> |
| <p><ins> |
| -16- <i>Replaceable:</i> a C++ program may define a function with this function |
| signature that displaces the default version defined by the C++ Standard |
| library. |
| </ins></p> |
| <p><ins> |
| -17- <i>Requires:</i> the value of <tt><i>ptr</i></tt> is null or the |
| value returned by an earlier call to the (possibly replaced) <tt>operator |
| new(std::size_t)</tt> or <tt>operator new(std::size_t, const |
| std::nothrow_t&)</tt>. </ins></p> |
| <p><ins> |
| -18- <i>Default behavior:</i> Calls <tt>operator delete(<i>ptr</i>)</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 18.5.1.2 [new.delete.array] |
| </p> |
| |
| <blockquote> |
| <pre>void* operator new[](std::size_t <i>size</i>, const std::nothrow_t&) throw(); |
| </pre> |
| |
| <blockquote> |
| <p> |
| -5- <i>Effects:</i> Same as above, except that it is called by a placement |
| version of a <i>new-expression</i> when a C++ program prefers a null pointer result as |
| an error indication, instead of a <tt>bad_alloc</tt> exception. |
| </p> |
| |
| <p> |
| -6- <i>Replaceable:</i> a C++ program can define a function with this function |
| signature that displaces the default version defined by the C++ Standard |
| library. |
| </p> |
| |
| <p> |
| -7- <i>Required behavior:</i> <del>Same as for operator <tt>new(std::size_t, |
| const std::nothrow_t&)</tt>. This nothrow version of operator <tt>new[]</tt> |
| returns a pointer obtained as if acquired from the ordinary version.</del> |
| <ins>Return a non-null pointer to suitably aligned storage (3.7.4), or else |
| return a null pointer. This nothrow version of operator new returns a pointer |
| obtained as if acquired from the (possibly replaced) <tt>operator |
| new[](std::size_t <i>size</i>)</tt>. This requirement is binding on a |
| replacement version of this function.</ins> |
| </p> |
| |
| <p> |
| -8- <i>Default behavior:</i> <del>Returns <tt>operator new(<i>size</i>, |
| nothrow)</tt>.</del> |
| </p> |
| |
| <ul> |
| <li><ins> |
| Calls <tt>operator new[](<i>size</i>)</tt>. |
| </ins></li> |
| <li><ins> |
| If the call to <tt>operator new[](<i>size</i>)</tt> returns normally, returns |
| the result of that call, else |
| </ins></li> |
| <li><ins> |
| if the call to <tt>operator new[](<i>size</i>)</tt> throws an exception, returns |
| a null pointer. |
| </ins></li> |
| </ul> |
| </blockquote> |
| |
| <pre>void operator delete[](void* <i>ptr</i>) throw(); |
| void operator delete[](void* <i>ptr</i>, const std::nothrow_t&) throw(); |
| </pre> |
| |
| <blockquote> |
| <p> |
| -9- <i>Effects:</i> The <i>deallocation function</i> (3.7.4.2) called by the |
| array form of a <i>delete-expression</i> to render the value of |
| <tt><i>ptr</i></tt> invalid. |
| </p> |
| |
| <p> |
| -10- <i>Replaceable:</i> a C++ program can define a function with this function |
| signature that displaces the default version defined by the C++ Standard |
| library. |
| </p> |
| |
| <p> |
| -11- <i>Requires:</i> the value of |
| <tt><i>ptr</i></tt> is null or the value returned by an earlier call to |
| <tt>operator new[](std::size_t)</tt> or <tt>operator new[](std::size_t, const |
| std::nothrow_t&)</tt>. |
| </p> |
| |
| <p> |
| -12- <i>Default behavior:</i> Calls <tt>operator delete(<i>ptr</i>)</tt> or |
| <tt>operator delete<ins>[]</ins>(<i>ptr</i><del>, std::nothrow</del>)</tt> respectively. |
| </p> |
| </blockquote> |
| |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Yes, they may become unlinked, and that is by design. If a user |
| replaces one, the user should also replace the other.</p> |
| |
| <p><i>[ |
| Reopened due to a gcc conversation between Howard, Martin and Gaby. Forwarding |
| or not is visible behavior to the client and it would be useful for the client |
| to know which behavior it could depend on. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Batavia: Robert voiced serious reservations about backwards compatibility for |
| his customers. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="208"></a>208. Unnecessary restriction on past-the-end iterators</h3> |
| <p><b>Section:</b> 24.1 [iterator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Stephen Cleary <b>Date:</b> 2000-02-02</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#iterator.requirements">active issues</a> in [iterator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iterator.requirements">issues</a> in [iterator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 24.1 paragraph 5, it is stated ". . . Dereferenceable and |
| past-the-end values are always non-singular."</p> |
| <p>This places an unnecessary restriction on past-the-end iterators for |
| containers with forward iterators (for example, a singly-linked list). If the |
| past-the-end value on such a container was a well-known singular value, it would |
| still satisfy all forward iterator requirements.</p> |
| <p>Removing this restriction would allow, for example, a singly-linked list |
| without a "footer" node.</p> |
| <p>This would have an impact on existing code that expects past-the-end |
| iterators obtained from different (generic) containers being not equal.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 24.1 [iterator.requirements] paragraph 5, the last sentence, from:</p> |
| <blockquote> |
| <p>Dereferenceable and past-the-end values are always non-singular.</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Dereferenceable values are always non-singular. </p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>For some kinds of containers, including singly linked lists and |
| zero-length vectors, null pointers are perfectly reasonable past-the-end |
| iterators. Null pointers are singular. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="209"></a>209. basic_string declarations inconsistent</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Igor Stauder <b>Date:</b> 2000-02-11</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In Section 21.3 [basic.string] the basic_string member function |
| declarations use a consistent style except for the following functions:</p> |
| <blockquote> |
| <pre>void push_back(const charT); |
| basic_string& assign(const basic_string&); |
| void swap(basic_string<charT,traits,Allocator>&);</pre> |
| </blockquote> |
| <p>- push_back, assign, swap: missing argument name <br> |
| - push_back: use of const with charT (i.e. POD type passed by value |
| not by reference - should be charT or const charT& )<br> |
| - swap: redundant use of template parameters in argument |
| basic_string<charT,traits,Allocator>&</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In Section 21.3 [basic.string] change the basic_string member |
| function declarations push_back, assign, and swap to:</p> |
| <blockquote> |
| <pre>void push_back(charT c); |
| |
| basic_string& assign(const basic_string& str); |
| void swap(basic_string& str);</pre> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Although the standard is in general not consistent in declaration |
| style, the basic_string declarations are consistent other than the |
| above. The LWG felt that this was sufficient reason to merit the |
| change. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="210"></a>210. distance first and last confused</h3> |
| <p><b>Section:</b> 25 [algorithms] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 2000-02-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#algorithms">issues</a> in [algorithms].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In paragraph 9 of section 25 [algorithms], it is written:</p> |
| <blockquote> |
| <p> In the description of the algorithms operators + and - are used |
| for some of the iterator categories for which they do not have to |
| be defined. In these cases the semantics of [...] a-b is the same |
| as of<br> |
| <br> |
| <tt>return distance(a, b);</tt></p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>On the last line of paragraph 9 of section 25 [algorithms] change |
| <tt>"a-b"</tt> to <tt>"b-a".</tt></p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>There are two ways to fix the defect; change the description to b-a |
| or change the return to distance(b,a). The LWG preferred the |
| former for consistency.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="211"></a>211. operator>>(istream&, string&) doesn't set failbit</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Scott Snyder <b>Date:</b> 2000-02-04</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The description of the stream extraction operator for std::string (section |
| 21.3.7.9 [lib.string.io]) does not contain a requirement that failbit be set in |
| the case that the operator fails to extract any characters from the input |
| stream.</p> |
| <p>This implies that the typical construction</p> |
| <blockquote> |
| <pre>std::istream is; |
| std::string str; |
| ... |
| while (is >> str) ... ;</pre> |
| </blockquote> |
| <p>(which tests failbit) is not required to terminate at EOF.</p> |
| <p>Furthermore, this is inconsistent with other extraction operators, |
| which do include this requirement. (See sections 27.6.1.2 [istream.formatted] and 27.6.1.3 [istream.unformatted]), where this |
| requirement is present, either explicitly or implicitly, for the |
| extraction operators. It is also present explicitly in the description |
| of getline (istream&, string&, charT) in section 21.3.8.9 [string.io] paragraph 8.)</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Insert new paragraph after paragraph 2 in section 21.3.8.9 [string.io]:</p> |
| <blockquote> |
| |
| <p>If the function extracts no characters, it calls |
| is.setstate(ios::failbit) which may throw ios_base::failure |
| (27.4.4.3).</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="212"></a>212. Empty range behavior unclear for several algorithms</h3> |
| <p><b>Section:</b> 25.3.7 [alg.min.max] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Nico Josuttis <b>Date:</b> 2000-02-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.min.max">issues</a> in [alg.min.max].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The standard doesn't specify what min_element() and max_element() shall |
| return if the range is empty (first equals last). The usual implementations |
| return last. This problem seems also apply to partition(), stable_partition(), |
| next_permutation(), and prev_permutation().</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.3.7 [alg.min.max] - Minimum and maximum, paragraphs 7 and |
| 9, append: Returns last if first==last.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG looked in some detail at all of the above mentioned |
| algorithms, but believes that except for min_element() and |
| max_element() it is already clear that last is returned if first == |
| last.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="214"></a>214. set::find() missing const overload</h3> |
| <p><b>Section:</b> 23.3.3 [set], 23.3.4 [multiset] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 2000-02-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#set">issues</a> in [set].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#450">450</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The specification for the associative container requirements in |
| Table 69 state that the find member function should "return |
| iterator; const_iterator for constant a". The map and multimap |
| container descriptions have two overloaded versions of find, but set |
| and multiset do not, all they have is:</p> |
| <blockquote> |
| <pre>iterator find(const key_type & x) const;</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the prototypes for find(), lower_bound(), upper_bound(), and |
| equal_range() in section 23.3.3 [set] and section 23.3.4 [multiset] to each have two overloads:</p> |
| <blockquote> |
| <pre>iterator find(const key_type & x); |
| const_iterator find(const key_type & x) const;</pre> |
| <pre>iterator lower_bound(const key_type & x); |
| const_iterator lower_bound(const key_type & x) const;</pre> |
| <pre>iterator upper_bound(const key_type & x); |
| const_iterator upper_bound(const key_type & x) const;</pre> |
| <pre>pair<iterator, iterator> equal_range(const key_type & x); |
| pair<const_iterator, const_iterator> equal_range(const key_type & x) const;</pre> |
| </blockquote> |
| |
| <p><i>[Tokyo: At the request of the LWG, Judy Ward provided wording |
| extending the proposed resolution to lower_bound, upper_bound, and |
| equal_range.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="217"></a>217. Facets example (Classifying Japanese characters) contains errors</h3> |
| <p><b>Section:</b> 22.2.8 [facets.examples] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-02-29</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facets.examples">issues</a> in [facets.examples].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The example in 22.2.8, paragraph 11 contains the following errors:</p> |
| <p>1) The member function `My::JCtype::is_kanji()' is non-const; the function |
| must be const in order for it to be callable on a const object (a reference to |
| which which is what std::use_facet<>() returns).</p> |
| <p>2) In file filt.C, the definition of `JCtype::id' must be qualified with the |
| name of the namespace `My'.</p> |
| <p>3) In the definition of `loc' and subsequently in the call to use_facet<>() |
| in main(), the name of the facet is misspelled: it should read `My::JCtype' |
| rather than `My::JCType'.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the "Classifying Japanese characters" example in 22.2.8, |
| paragraph 11 with the following:</p> |
| <pre>#include <locale></pre> |
| <pre>namespace My { |
| using namespace std; |
| class JCtype : public locale::facet { |
| public: |
| static locale::id id; // required for use as a new locale facet |
| bool is_kanji (wchar_t c) const; |
| JCtype() {} |
| protected: |
| ~JCtype() {} |
| }; |
| }</pre> |
| <pre>// file: filt.C |
| #include <iostream> |
| #include <locale> |
| #include "jctype" // above |
| std::locale::id My::JCtype::id; // the static JCtype member |
| declared above.</pre> |
| <pre>int main() |
| { |
| using namespace std; |
| typedef ctype<wchar_t> wctype; |
| locale loc(locale(""), // the user's preferred locale... |
| new My::JCtype); // and a new feature ... |
| wchar_t c = use_facet<wctype>(loc).widen('!'); |
| if (!use_facet<My::JCtype>(loc).is_kanji(c)) |
| cout << "no it isn't!" << endl; |
| return 0; |
| }</pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="220"></a>220. ~ios_base() usage valid?</h3> |
| <p><b>Section:</b> 27.4.2.7 [ios.base.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Jonathan Schilling, Howard Hinnant <b>Date:</b> 2000-03-13</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The pre-conditions for the ios_base destructor are described in 27.4.2.7 |
| paragraph 2:</p> |
| <blockquote> |
| <p>Effects: Destroys an object of class ios_base. Calls each registered |
| callback pair (fn,index) (27.4.2.6) as (*fn)(erase_event,*this,index) at such |
| time that any ios_base member function called from within fn has well defined |
| results.</p> |
| </blockquote> |
| <p>But what is not clear is: If no callback functions were ever registered, does |
| it matter whether the ios_base members were ever initialized?</p> |
| <p>For instance, does this program have defined behavior:</p> |
| <blockquote> |
| <pre>#include <ios></pre> |
| <pre>class D : public std::ios_base { };</pre> |
| <pre>int main() { D d; }</pre> |
| </blockquote> |
| <p>It seems that registration of a callback function would surely affect the |
| state of an ios_base. That is, when you register a callback function with an |
| ios_base, the ios_base must record that fact somehow.</p> |
| <p>But if after construction the ios_base is in an indeterminate state, and that |
| state is not made determinate before the destructor is called, then how would |
| the destructor know if any callbacks had indeed been registered? And if the |
| number of callbacks that had been registered is indeterminate, then is not the |
| behavior of the destructor undefined?</p> |
| <p>By comparison, the basic_ios class description in 27.4.4.1 paragraph 2 makes |
| it explicit that destruction before initialization results in undefined |
| behavior.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Modify 27.4.2.7 paragraph 1 from</p> |
| <blockquote> |
| <p>Effects: Each ios_base member has an indeterminate value after |
| construction.</p> |
| </blockquote> |
| <p>to</p> |
| <blockquote> |
| <p>Effects: Each ios_base member has an indeterminate |
| value after construction. These members must be initialized by calling |
| basic_ios::init. If an ios_base object is destroyed before these |
| initializations have taken place, the behavior is undefined.</p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="221"></a>221. num_get<>::do_get stage 2 processing broken</h3> |
| <p><b>Section:</b> 22.2.2.1.2 [facet.num.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2000-03-14</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Stage 2 processing of numeric conversion is broken.</p> |
| |
| <p>Table 55 in 22.2.2.1.2 says that when basefield is 0 the integral |
| conversion specifier is %i. A %i specifier determines a number's base |
| by its prefix (0 for octal, 0x for hex), so the intention is clearly |
| that a 0x prefix is allowed. Paragraph 8 in the same section, |
| however, describes very precisely how characters are processed. (It |
| must be done "as if" by a specified code fragment.) That |
| description does not allow a 0x prefix to be recognized.</p> |
| |
| <p>Very roughly, stage 2 processing reads a char_type ct. It converts |
| ct to a char, not by using narrow but by looking it up in a |
| translation table that was created by widening the string literal |
| "0123456789abcdefABCDEF+-". The character "x" is |
| not found in that table, so it can't be recognized by stage 2 |
| processing.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.2 paragraph 8, replace the line:</p> |
| <blockquote> |
| <pre>static const char src[] = "0123456789abcdefABCDEF+-";</pre> |
| </blockquote> |
| <p>with the line:</p> |
| <blockquote> |
| <pre>static const char src[] = "0123456789abcdefxABCDEFX+-";</pre> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>If we're using the technique of widening a string literal, the |
| string literal must contain every character we wish to recognize. |
| This technique has the consequence that alternate representations |
| of digits will not be recognized. This design decision was made |
| deliberately, with full knowledge of that limitation.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="222"></a>222. Are throw clauses necessary if a throw is already implied by the effects clause?</h3> |
| <p><b>Section:</b> 17.3.1.3 [structure.specifications] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 2000-03-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#structure.specifications">issues</a> in [structure.specifications].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 21.3.6.8 describes the basic_string::compare function this way:</p> |
| <blockquote> |
| <pre>21.3.6.8 - basic_string::compare [lib.string::compare] |
| |
| int compare(size_type pos1, size_type n1, |
| const basic_string<charT,traits,Allocator>& str , |
| size_type pos2 , size_type n2 ) const; |
| |
| -4- Returns: |
| |
| basic_string<charT,traits,Allocator>(*this,pos1,n1).compare( |
| basic_string<charT,traits,Allocator>(str,pos2,n2)) .</pre> |
| </blockquote> |
| <p>and the constructor that's implicitly called by the above is |
| defined to throw an out-of-range exception if pos > str.size(). See |
| section 21.3.1 [string.require] paragraph 4.</p> |
| |
| <p>On the other hand, the compare function descriptions themselves don't have |
| "Throws: " clauses and according to 17.3.1.3, paragraph 3, elements |
| that do not apply to a function are omitted.</p> |
| <p>So it seems there is an inconsistency in the standard -- are the |
| "Effects" clauses correct, or are the "Throws" clauses |
| missing?</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 17.3.1.3 [structure.specifications] paragraph 3, the footnote 148 attached to |
| the sentence "Descriptions of function semantics contain the |
| following elements (as appropriate):", insert the word |
| "further" so that the foot note reads:</p> |
| <blockquote> |
| <p>To save space, items that do not apply to a function are |
| omitted. For example, if a function does not specify any further |
| preconditions, there will be no "Requires" paragraph.</p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The standard is somewhat inconsistent, but a failure to note a |
| throw condition in a throws clause does not grant permission not to |
| throw. The inconsistent wording is in a footnote, and thus |
| non-normative. The proposed resolution from the LWG clarifies the |
| footnote.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="223"></a>223. reverse algorithm should use iter_swap rather than swap</h3> |
| <p><b>Section:</b> 25.2.10 [alg.reverse] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2000-03-21</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Shouldn't the effects say "applies iter_swap to all pairs..."?</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.2.10 [alg.reverse], replace:</p> |
| <blockquote><p> |
| Effects: For each non-negative integer i <= (last - first)/2, |
| applies swap to all pairs of iterators first + i, (last - i) - 1. |
| </p></blockquote> |
| <p>with:</p> |
| <blockquote><p> |
| Effects: For each non-negative integer i <= (last - first)/2, |
| applies iter_swap to all pairs of iterators first + i, (last - i) - 1. |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="224"></a>224. clear() complexity for associative containers refers to undefined N</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Ed Brey <b>Date:</b> 2000-03-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In the associative container requirements table in 23.1.2 paragraph 7, |
| a.clear() has complexity "log(size()) + N". However, the meaning of N |
| is not defined.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the associative container requirements table in 23.1.2 paragraph |
| 7, the complexity of a.clear(), change "log(size()) + N" to |
| "linear in <tt>size()</tt>".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>It's the "log(size())", not the "N", that is in |
| error: there's no difference between <i>O(N)</i> and <i>O(N + |
| log(N))</i>. The text in the standard is probably an incorrect |
| cut-and-paste from the range version of <tt>erase</tt>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="225"></a>225. std:: algorithms use of other unqualified algorithms</h3> |
| <p><b>Section:</b> 17.4.4.3 [global.functions] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2000-04-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#global.functions">issues</a> in [global.functions].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Are algorithms in std:: allowed to use other algorithms without qualification, so functions in |
| user namespaces might be found through Koenig lookup?</p> |
| <p>For example, a popular standard library implementation includes this |
| implementation of std::unique:</p> |
| <blockquote> |
| <pre>namespace std { |
| template <class _ForwardIter> |
| _ForwardIter unique(_ForwardIter __first, _ForwardIter __last) { |
| __first = adjacent_find(__first, __last); |
| return unique_copy(__first, __last, __first); |
| } |
| }</pre> |
| </blockquote> |
| <p>Imagine two users on opposite sides of town, each using unique on his own |
| sequences bounded by my_iterators . User1 looks at his standard library |
| implementation and says, "I know how to implement a more efficient |
| unique_copy for my_iterators", and writes:</p> |
| <blockquote> |
| <pre>namespace user1 { |
| class my_iterator; |
| // faster version for my_iterator |
| my_iterator unique_copy(my_iterator, my_iterator, my_iterator); |
| }</pre> |
| </blockquote> |
| <p>user1::unique_copy() is selected by Koenig lookup, as he intended.</p> |
| <p>User2 has other needs, and writes:</p> |
| <blockquote> |
| <pre>namespace user2 { |
| class my_iterator; |
| // Returns true iff *c is a unique copy of *a and *b. |
| bool unique_copy(my_iterator a, my_iterator b, my_iterator c); |
| }</pre> |
| </blockquote> |
| <p>User2 is shocked to find later that his fully-qualified use of |
| std::unique(user2::my_iterator, user2::my_iterator, user2::my_iterator) fails to |
| compile (if he's lucky). Looking in the standard, he sees the following Effects |
| clause for unique():</p> |
| <blockquote> |
| <p>Effects: Eliminates all but the first element from every consecutive group |
| of equal elements referred to by the iterator i in the range [first, last) for |
| which the following corresponding conditions hold: *i == *(i - 1) or pred(*i, |
| *(i - 1)) != false</p> |
| </blockquote> |
| <p>The standard gives user2 absolutely no reason to think he can interfere with |
| std::unique by defining names in namespace user2. His standard library has been |
| built with the template export feature, so he is unable to inspect the |
| implementation. User1 eventually compiles his code with another compiler, and |
| his version of unique_copy silently stops being called. Eventually, he realizes |
| that he was depending on an implementation detail of his library and had no |
| right to expect his unique_copy() to be called portably.</p> |
| <p>On the face of it, and given above scenario, it may seem obvious that the |
| implementation of unique() shown is non-conforming because it uses unique_copy() |
| rather than ::std::unique_copy(). Most standard library implementations, |
| however, seem to disagree with this notion.</p> |
| <p> <i>[Tokyo: Steve Adamczyk from |
| the core working group indicates that "std::" is sufficient; |
| leading "::" qualification is not required because any namespace |
| qualification is sufficient to suppress Koenig lookup.]</i></p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a paragraph and a note at the end of |
| 17.4.4.3 [global.functions]:</p> |
| <blockquote> |
| |
| <p>Unless otherwise specified, no global or non-member function in the |
| standard library shall use a function from another namespace which is |
| found through <i>argument-dependent name lookup</i> (3.4.2 [basic.lookup.argdep]).</p> |
| |
| <p>[Note: the phrase "unless otherwise specified" is intended to |
| allow Koenig lookup in cases like that of ostream_iterators:<br> |
| |
| <br> |
| Effects:</p> |
| <blockquote> |
| <p>*out_stream << value;<br> |
| if(delim != 0) *out_stream << delim;<br> |
| return (*this);</p> |
| <p>--end note]</p> |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[Tokyo: The LWG agrees that this is a defect in the standard, but |
| is as yet unsure if the proposed resolution is the best |
| solution. Furthermore, the LWG believes that the same problem of |
| unqualified library names applies to wording in the standard itself, |
| and has opened issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a> accordingly. Any resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> should be coordinated with the resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#229">229</a>.]</i></p> |
| |
| |
| <p><i>[Toronto: The LWG is not sure if this is a defect in the |
| standard. Most LWG members believe that an implementation of |
| <tt>std::unique</tt> like the one quoted in this issue is already |
| illegal, since, under certain circumstances, its semantics are not |
| those specified in the standard. The standard's description of |
| <tt>unique</tt> does not say that overloading <tt>adjacent_find</tt> |
| should have any effect.]</i></p> |
| |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. The proposed |
| resolution for this issue is in accordance with Howard's paper.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>It could be argued that this proposed isn't strictly necessary, |
| that the Standard doesn't grant implementors license to write a |
| standard function that behaves differently than specified in the |
| Standard just because of an unrelated user-defined name in some |
| other namespace. However, this is at worst a clarification. It is |
| surely right that algorithsm shouldn't pick up random names, that |
| user-defined names should have no effect unless otherwise specified. |
| Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#226">226</a> deals with the question of when it is |
| appropriate for the standard to explicitly specify otherwise.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="226"></a>226. User supplied specializations or overloads of namespace std function templates</h3> |
| <p><b>Section:</b> 17.4.3.2 [reserved.names] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2000-04-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#reserved.names">issues</a> in [reserved.names].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The issues are: </p> |
| <p>1. How can a 3rd party library implementor (lib1) write a version of a standard |
| algorithm which is specialized to work with his own class template? </p> |
| <p>2. How can another library implementor (lib2) write a generic algorithm which |
| will take advantage of the specialized algorithm in lib1?</p> |
| <p>This appears to be the only viable answer under current language rules:</p> |
| <blockquote> |
| <pre>namespace lib1 |
| { |
| // arbitrary-precision numbers using T as a basic unit |
| template <class T> |
| class big_num { //... |
| }; |
| </pre> |
| <pre> // defining this in namespace std is illegal (it would be an |
| // overload), so we hope users will rely on Koenig lookup |
| template <class T> |
| void swap(big_int<T>&, big_int<T>&); |
| }</pre> |
| <pre>#include <algorithm> |
| namespace lib2 |
| { |
| template <class T> |
| void generic_sort(T* start, T* end) |
| { |
| ... |
| // using-declaration required so we can work on built-in types |
| using std::swap; |
| // use Koenig lookup to find specialized algorithm if available |
| swap(*x, *y); |
| } |
| }</pre> |
| </blockquote> |
| <p>This answer has some drawbacks. First of all, it makes writing lib2 difficult |
| and somewhat slippery. The implementor needs to remember to write the |
| using-declaration, or generic_sort will fail to compile when T is a built-in |
| type. The second drawback is that the use of this style in lib2 effectively |
| "reserves" names in any namespace which defines types which may |
| eventually be used with lib2. This may seem innocuous at first when applied to |
| names like swap, but consider more ambiguous names like unique_copy() instead. |
| It is easy to imagine the user wanting to define these names differently in his |
| own namespace. A definition with semantics incompatible with the standard |
| library could cause serious problems (see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>).</p> |
| <p>Why, you may ask, can't we just partially specialize std::swap()? It's |
| because the language doesn't allow for partial specialization of function |
| templates. If you write:</p> |
| <blockquote> |
| <pre>namespace std |
| { |
| template <class T> |
| void swap(lib1::big_int<T>&, lib1::big_int<T>&); |
| }</pre> |
| </blockquote> |
| <p>You have just overloaded std::swap, which is illegal under the current |
| language rules. On the other hand, the following full specialization is legal:</p> |
| <blockquote> |
| <pre>namespace std |
| { |
| template <> |
| void swap(lib1::other_type&, lib1::other_type&); |
| }</pre> |
| </blockquote> |
| |
| <p>This issue reflects concerns raised by the "Namespace issue |
| with specialized swap" thread on comp.lang.c++.moderated. A |
| similar set of concerns was earlier raised on the boost.org mailing |
| list and the ACCU-general mailing list. Also see library reflector |
| message c++std-lib-7354.</p> |
| |
| <p> |
| J. C. van Winkel points out (in c++std-lib-9565) another unexpected |
| fact: it's impossible to output a container of std::pair's using copy |
| and an ostream_iterator, as long as both pair-members are built-in or |
| std:: types. That's because a user-defined operator<< for (for |
| example) std::pair<const std::string, int> will not be found: |
| lookup for operator<< will be performed only in namespace std. |
| Opinions differed on whether or not this was a defect, and, if so, |
| whether the defect is that something is wrong with user-defined |
| functionality and std, or whether it's that the standard library does |
| not provide an operator<< for std::pair<>. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Adopt the wording proposed in Howard Hinnant's paper |
| N1523=03-0106, "Proposed Resolution To LWG issues 225, 226, 229".</p> |
| |
| |
| <p><i>[Tokyo: Summary, "There is no conforming way to extend |
| std::swap for user defined templates." The LWG agrees that |
| there is a problem. Would like more information before |
| proceeding. This may be a core issue. Core issue 229 has been opened |
| to discuss the core aspects of this problem. It was also noted that |
| submissions regarding this issue have been received from several |
| sources, but too late to be integrated into the issues list. |
| ]</i></p> |
| |
| |
| <p><i>[Post-Tokyo: A paper with several proposed resolutions, |
| J16/00-0029==WG21/N1252, "Shades of namespace std functions |
| " by Alan Griffiths, is in the Post-Tokyo mailing. It |
| should be considered a part of this issue.]</i></p> |
| |
| |
| <p><i>[Toronto: Dave Abrahams and Peter Dimov have proposed a |
| resolution that involves core changes: it would add partial |
| specialization of function template. The Core Working Group is |
| reluctant to add partial specialization of function templates. It is |
| viewed as a large change, CWG believes that proposal presented leaves |
| some syntactic issues unanswered; if the CWG does add partial |
| specialization of function templates, it wishes to develop its own |
| proposal. The LWG continues to believe that there is a serious |
| problem: there is no good way for users to force the library to use |
| user specializations of generic standard library functions, and in |
| certain cases (e.g. transcendental functions called by |
| <tt>valarray</tt> and <tt>complex</tt>) this is important. Koenig |
| lookup isn't adequate, since names within the library must be |
| qualified with <tt>std</tt> (see issue 225), specialization doesn't |
| work (we don't have partial specialization of function templates), and |
| users aren't permitted to add overloads within namespace std. |
| ]</i></p> |
| |
| |
| <p><i>[Copenhagen: Discussed at length, with no consensus. Relevant |
| papers in the pre-Copenhagen mailing: N1289, N1295, N1296. Discussion |
| focused on four options. (1) Relax restrictions on overloads within |
| namespace std. (2) Mandate that the standard library use unqualified |
| calls for <tt>swap</tt> and possibly other functions. (3) Introduce |
| helper class templates for <tt>swap</tt> and possibly other functions. |
| (4) Introduce partial specialization of function templates. Every |
| option had both support and opposition. Straw poll (first number is |
| support, second is strongly opposed): (1) 6, 4; (2) 6, 7; (3) 3, 8; |
| (4) 4, 4.]</i></p> |
| |
| |
| <p><i>[Redmond: Discussed, again no consensus. Herb presented an |
| argument that a user who is defining a type <tt>T</tt> with an |
| associated <tt>swap</tt> should not be expected to put that |
| <tt>swap</tt> in namespace std, either by overloading or by partial |
| specialization. The argument is that <tt>swap</tt> is part of |
| <tt>T</tt>'s interface, and thus should to in the same namespace as |
| <tt>T</tt> and only in that namespace. If we accept this argument, |
| the consequence is that standard library functions should use |
| unqualified call of <tt>swap</tt>. (And which other functions? Any?) |
| A small group (Nathan, Howard, Jeremy, Dave, Matt, Walter, Marc) will |
| try to put together a proposal before the next meeting.]</i></p> |
| |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. The proposed |
| resolution is the one proposed by Howard.]</i></p> |
| |
| |
| <p><i>[Santa Cruz: the LWG agreed with the general direction of |
| Howard's paper, N1387. (Roughly: Koenig lookup is disabled unless |
| we say otherwise; this issue is about when we do say otherwise.) |
| However, there were concerns about wording. Howard will provide new |
| wording. Bill and Jeremy will review it.]</i></p> |
| |
| |
| <p><i>[Kona: Howard proposed the new wording. The LWG accepted his |
| proposed resolution.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Informally: introduce a Swappable concept, and specify that the |
| value types of the iterators passed to certain standard algorithms |
| (such as iter_swap, swap_ranges, reverse, rotate, and sort) conform |
| to that concept. The Swappable concept will make it clear that |
| these algorithms use unqualified lookup for the calls |
| to <tt>swap</tt>. Also, in 26.5.3.3 [valarray.transcend] paragraph 1, |
| state that the valarray transcendentals use unqualified lookup.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="227"></a>227. std::swap() should require CopyConstructible or DefaultConstructible arguments</h3> |
| <p><b>Section:</b> 25.2.3 [alg.swap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TC">TC</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2000-04-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.swap">issues</a> in [alg.swap].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TC">TC</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>25.2.2 reads:</p> |
| <blockquote> |
| <p><tt> template<class T> void swap(T& a, T& b);</tt><br> |
| <br> |
| Requires: Type T is Assignable (_lib.container.requirements_).<br> |
| Effects: Exchanges values stored in two locations.</p> |
| </blockquote> |
| <p>The only reasonable** generic implementation of swap requires construction of a |
| new temporary copy of one of its arguments:</p> |
| <blockquote> |
| <pre>template<class T> void swap(T& a, T& b); |
| { |
| T tmp(a); |
| a = b; |
| b = tmp; |
| }</pre> |
| </blockquote> |
| <p>But a type which is only Assignable cannot be swapped by this implementation.</p> |
| <p>**Yes, there's also an unreasonable implementation which would require T to be |
| DefaultConstructible instead of CopyConstructible. I don't think this is worthy |
| of consideration:</p> |
| <blockquote> |
| <pre>template<class T> void swap(T& a, T& b); |
| { |
| T tmp; |
| tmp = a; |
| a = b; |
| b = tmp; |
| }</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.2.2 paragraph 1 from:</p> |
| <blockquote> |
| <p> Requires: Type T is Assignable (23.1).</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p> Requires: Type T is CopyConstructible (20.1.3) and Assignable (23.1)</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="228"></a>228. Incorrect specification of "..._byname" facets</h3> |
| <p><b>Section:</b> 22.2 [locale.categories] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 2000-04-20</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#locale.categories">active issues</a> in [locale.categories].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.categories">issues</a> in [locale.categories].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The sections 22.2.1.2 [locale.ctype.byname], 22.2.1.5 |
| [locale.codecvt.byname], |
| sref ref="22.2.1.6", 22.2.3.2 [locale.numpunct.byname], 22.2.4.2 |
| [locale.collate.byname], 22.2.5.4 [locale.time.put.byname], 22.2.6.4 |
| [locale.moneypunct.byname], and 22.2.7.2 [locale.messages.byname] |
| overspecify the |
| definitions of the "..._byname" classes by listing a bunch |
| of virtual functions. At the same time, no semantics of these |
| functions are defined. Real implementations do not define these |
| functions because the functional part of the facets is actually |
| implemented in the corresponding base classes and the constructor of |
| the "..._byname" version just provides suitable date used by |
| these implementations. For example, the 'numpunct' methods just return |
| values from a struct. The base class uses a statically initialized |
| struct while the derived version reads the contents of this struct |
| from a table. However, no virtual function is defined in |
| 'numpunct_byname'.</p> |
| |
| <p>For most classes this does not impose a problem but specifically |
| for 'ctype' it does: The specialization for 'ctype_byname<char>' |
| is required because otherwise the semantics would change due to the |
| virtual functions defined in the general version for 'ctype_byname': |
| In 'ctype<char>' the method 'do_is()' is not virtual but it is |
| made virtual in both 'ctype<cT>' and 'ctype_byname<cT>'. |
| Thus, a class derived from 'ctype_byname<char>' can tell whether |
| this class is specialized or not under the current specification: |
| Without the specialization, 'do_is()' is virtual while with |
| specialization it is not virtual.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> Change section 22.2.1.2 (lib.locale.ctype.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class ctype_byname : public ctype<charT> { |
| public: |
| typedef ctype<charT>::mask mask; |
| explicit ctype_byname(const char*, size_t refs = 0); |
| protected: |
| ~ctype_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.1.6 (lib.locale.codecvt.byname) to become:</p> |
| <pre> namespace std { |
| template <class internT, class externT, class stateT> |
| class codecvt_byname : public codecvt<internT, externT, stateT> { |
| public: |
| explicit codecvt_byname(const char*, size_t refs = 0); |
| protected: |
| ~codecvt_byname(); // virtual |
| }; |
| } |
| </pre> |
| <p> Change section 22.2.3.2 (lib.locale.numpunct.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class numpunct_byname : public numpunct<charT> { |
| // this class is specialized for char and wchar_t. |
| public: |
| typedef charT char_type; |
| typedef basic_string<charT> string_type; |
| explicit numpunct_byname(const char*, size_t refs = 0); |
| protected: |
| ~numpunct_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.4.2 (lib.locale.collate.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class collate_byname : public collate<charT> { |
| public: |
| typedef basic_string<charT> string_type; |
| explicit collate_byname(const char*, size_t refs = 0); |
| protected: |
| ~collate_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.5.2 (lib.locale.time.get.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, class InputIterator = istreambuf_iterator<charT> > |
| class time_get_byname : public time_get<charT, InputIterator> { |
| public: |
| typedef time_base::dateorder dateorder; |
| typedef InputIterator iter_type</pre> |
| <pre> explicit time_get_byname(const char*, size_t refs = 0); |
| protected: |
| ~time_get_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.5.4 (lib.locale.time.put.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, class OutputIterator = ostreambuf_iterator<charT> > |
| class time_put_byname : public time_put<charT, OutputIterator> |
| { |
| public: |
| typedef charT char_type; |
| typedef OutputIterator iter_type;</pre> |
| <pre> explicit time_put_byname(const char*, size_t refs = 0); |
| protected: |
| ~time_put_byname(); // virtual |
| }; |
| }"</pre> |
| <p> Change section 22.2.6.4 (lib.locale.moneypunct.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT, bool Intl = false> |
| class moneypunct_byname : public moneypunct<charT, Intl> { |
| public: |
| typedef money_base::pattern pattern; |
| typedef basic_string<charT> string_type;</pre> |
| <pre> explicit moneypunct_byname(const char*, size_t refs = 0); |
| protected: |
| ~moneypunct_byname(); // virtual |
| }; |
| }</pre> |
| <p> Change section 22.2.7.2 (lib.locale.messages.byname) to become:</p> |
| <pre> namespace std { |
| template <class charT> |
| class messages_byname : public messages<charT> { |
| public: |
| typedef messages_base::catalog catalog; |
| typedef basic_string<charT> string_type;</pre> |
| <pre> explicit messages_byname(const char*, size_t refs = 0); |
| protected: |
| ~messages_byname(); // virtual |
| }; |
| }</pre> |
| <p>Remove section 22.2.1.4 [locale.codecvt] completely (because in |
| this case only those members are defined to be virtual which are |
| defined to be virtual in 'ctype<cT>'.)</p> |
| |
| <p><i>[Post-Tokyo: Dietmar Kühl submitted this issue at the request of |
| the LWG to solve the underlying problems raised by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#138">138</a>.]</i></p> |
| |
| |
| <p><i>[Copenhagen: proposed resolution was revised slightly, to remove |
| three last virtual functions from <tt>messages_byname</tt>.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="229"></a>229. Unqualified references of other library entities</h3> |
| <p><b>Section:</b> 17.4.1.1 [contents] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 2000-04-19</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Throughout the library chapters, the descriptions of library entities refer |
| to other library entities without necessarily qualifying the names.</p> |
| |
| <p>For example, section 25.2.2 "Swap" describes the effect of |
| swap_ranges in terms of the unqualified name "swap". This section |
| could reasonably be interpreted to mean that the library must be implemented so |
| as to do a lookup of the unqualified name "swap", allowing users to |
| override any ::std::swap function when Koenig lookup applies.</p> |
| |
| <p>Although it would have been best to use explicit qualification with |
| "::std::" throughout, too many lines in the standard would have to be |
| adjusted to make that change in a Technical Corrigendum.</p> |
| |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#182">182</a>, which addresses qualification of |
| <tt>size_t</tt>, is a special case of this. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>To section 17.4.1.1 "Library contents" Add the following paragraph:</p> |
| <blockquote> |
| <p>Whenever a name x defined in the standard library is mentioned, the name x |
| is assumed to be fully qualified as ::std::x, unless explicitly described |
| otherwise. For example, if the Effects section for library function F is |
| described as calling library function G, the function ::std::G is meant.</p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: Steve Clamage submitted this issue at the request of |
| the LWG to solve a problem in the standard itself similar to the |
| problem within implementations of library identified by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a>. Any resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#225">225</a> should be |
| coordinated with the resolution of this issue.]</i></p> |
| |
| |
| <p><i>[post-Toronto: Howard is undecided about whether it is |
| appropriate for all standard library function names referred to in |
| other standard library functions to be explicitly qualified by |
| <tt>std</tt>: it is common advice that users should define global |
| functions that operate on their class in the same namespace as the |
| class, and this requires argument-dependent lookup if those functions |
| are intended to be called by library code. Several LWG members are |
| concerned that valarray appears to require argument-dependent lookup, |
| but that the wording may not be clear enough to fall under |
| "unless explicitly described otherwise".]</i></p> |
| |
| |
| <p><i>[Curaçao: An LWG-subgroup spent an afternoon working on issues |
| 225, 226, and 229. Their conclusion was that the issues should be |
| separated into an LWG portion (Howard's paper, N1387=02-0045), and a |
| EWG portion (Dave will write a proposal). The LWG and EWG had |
| (separate) discussions of this plan the next day. This paper resolves |
| issues 225 and 226. In light of that resolution, the proposed |
| resolution for the current issue makes sense.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="230"></a>230. Assignable specified without also specifying CopyConstructible</h3> |
| <p><b>Section:</b> 17 [library] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2000-04-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#library">issues</a> in [library].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#227">227</a> identified an instance (std::swap) where |
| Assignable was specified without also specifying |
| CopyConstructible. The LWG asked that the standard be searched to |
| determine if the same defect existed elsewhere.</p> |
| |
| <p>There are a number of places (see proposed resolution below) where |
| Assignable is specified without also specifying |
| CopyConstructible. There are also several cases where both are |
| specified. For example, 26.4.1 [rand.req].</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.1 [container.requirements] table 65 for value_type: |
| change "T is Assignable" to "T is CopyConstructible and |
| Assignable" |
| </p> |
| |
| <p>In 23.1.4 [associative.reqmts] table 69 X::key_type; change |
| "Key is Assignable" to "Key is |
| CopyConstructible and Assignable"<br> |
| </p> |
| |
| <p>In 24.1.2 [output.iterators] paragraph 1, change: |
| </p> |
| <blockquote> |
| <p> A class or a built-in type X satisfies the requirements of an |
| output iterator if X is an Assignable type (23.1) and also the |
| following expressions are valid, as shown in Table 73: |
| </p> |
| </blockquote> |
| <p>to: |
| </p> |
| <blockquote> |
| <p> A class or a built-in type X satisfies the requirements of an |
| output iterator if X is a CopyConstructible (20.1.3) and Assignable |
| type (23.1) and also the following expressions are valid, as shown in |
| Table 73: |
| </p> |
| </blockquote> |
| |
| <p><i>[Post-Tokyo: Beman Dawes submitted this issue at the request of |
| the LWG. He asks that the 25.2.5 [alg.replace] and 25.2.6 [alg.fill] changes be studied carefully, as it is not clear that |
| CopyConstructible is really a requirement and may be |
| overspecification.]</i></p> |
| |
| |
| <p><i>[Portions of the resolution for issue 230 have been superceded by |
| the resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#276">276</a>.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution also included changes to input |
| iterator, fill, and replace. The LWG believes that those changes are |
| not necessary. The LWG considered some blanket statement, where an |
| Assignable type was also required to be Copy Constructible, but |
| decided against this because fill and replace really don't require the |
| Copy Constructible property.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="231"></a>231. Precision in iostream?</h3> |
| <p><b>Section:</b> 22.2.2.2.2 [facet.num.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> James Kanze, Stephen Clamage <b>Date:</b> 2000-04-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.put.virtuals">issues</a> in [facet.num.put.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>What is the following program supposed to output?</p> |
| <pre>#include <iostream> |
| |
| int |
| main() |
| { |
| std::cout.setf( std::ios::scientific , std::ios::floatfield ) ; |
| std::cout.precision( 0 ) ; |
| std::cout << 1.00 << '\n' ; |
| return 0 ; |
| }</pre> |
| <p>From my C experience, I would expect "1e+00"; this is what |
| <tt>printf("%.0e" , 1.00 );</tt> does. G++ outputs |
| "1.000000e+00".</p> |
| |
| <p>The only indication I can find in the standard is 22.2.2.2.2/11, |
| where it says "For conversion from a floating-point type, if |
| (flags & fixed) != 0 or if str.precision() > 0, then |
| str.precision() is specified in the conversion specification." |
| This is an obvious error, however, fixed is not a mask for a field, |
| but a value that a multi-bit field may take -- the results of and'ing |
| fmtflags with ios::fixed are not defined, at least not if |
| ios::scientific has been set. G++'s behavior corresponds to what might |
| happen if you do use (flags & fixed) != 0 with a typical |
| implementation (floatfield == 3 << something, fixed == 1 |
| << something, and scientific == 2 << something).</p> |
| |
| <p>Presumably, the intent is either (flags & floatfield) != 0, or |
| (flags & floatfield) == fixed; the first gives something more or |
| less like the effect of precision in a printf floating point |
| conversion. Only more or less, of course. In order to implement printf |
| formatting correctly, you must know whether the precision was |
| explicitly set or not. Say by initializing it to -1, instead of 6, and |
| stating that for floating point conversions, if precision < -1, 6 |
| will be used, for fixed point, if precision < -1, 1 will be used, |
| etc. Plus, of course, if precision == 0 and flags & floatfield == |
| 0, 1 should be = used. But it probably isn't necessary to emulate all |
| of the anomalies of printf:-).</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace 22.2.2.2.2 [facet.num.put.virtuals], paragraph 11, with the following |
| sentence: |
| </p> |
| <blockquote><p> |
| For conversion from a floating-point type, |
| <tt><i>str</i>.precision()</tt> is specified in the conversion |
| specification. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The floatfield determines whether numbers are formatted as if |
| with %f, %e, or %g. If the <tt>fixed</tt> bit is set, it's %f, |
| if <tt>scientific</tt> it's %e, and if both bits are set, or |
| neither, it's %g.</p> |
| <p>Turning to the C standard, a precision of 0 is meaningful |
| for %f and %e. For %g, precision 0 is taken to be the same as |
| precision 1.</p> |
| <p>The proposed resolution has the effect that if neither |
| <tt>fixed</tt> nor <tt>scientific</tt> is set we'll be |
| specifying a precision of 0, which will be internally |
| turned into 1. There's no need to call it out as a special |
| case.</p> |
| <p>The output of the above program will be "1e+00".</p> |
| |
| <p><i>[Post-Curaçao: Howard provided improved wording covering the case |
| where precision is 0 and mode is %g.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="232"></a>232. "depends" poorly defined in 17.4.3.1</h3> |
| <p><b>Section:</b> 17.4.3.2 [reserved.names] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2000-04-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#reserved.names">issues</a> in [reserved.names].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>17.4.3.1/1 uses the term "depends" to limit the set of allowed |
| specializations of standard templates to those that "depend on a |
| user-defined name of external linkage."</p> |
| <p>This term, however, is not adequately defined, making it possible to |
| construct a specialization that is, I believe, technically legal according to |
| 17.4.3.1/1, but that specializes a standard template for a built-in type such as |
| 'int'.</p> |
| <p>The following code demonstrates the problem:</p> |
| <blockquote> |
| <pre>#include <algorithm></pre> |
| <pre>template<class T> struct X |
| { |
| typedef T type; |
| };</pre> |
| <pre>namespace std |
| { |
| template<> void swap(::X<int>::type& i, ::X<int>::type& j); |
| }</pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change "user-defined name" to "user-defined |
| type".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This terminology is used in section 2.5.2 and 4.1.1 of <i>The C++ |
| Programming Language</i>. It disallows the example in the issue, |
| since the underlying type itself is not user-defined. The only |
| possible problem I can see is for non-type templates, but there's no |
| possible way for a user to come up with a specialization for bitset, |
| for example, that might not have already been specialized by the |
| implementor?</p> |
| |
| <p><i>[Toronto: this may be related to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#120">120</a>.]</i></p> |
| |
| |
| <p><i>[post-Toronto: Judy provided the above proposed resolution and |
| rationale.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="233"></a>233. Insertion hints in associative containers</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andrew Koenig <b>Date:</b> 2000-04-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#192">192</a>, <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#246">246</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| If <tt>mm</tt> is a multimap and <tt>p</tt> is an iterator |
| into the multimap, then <tt>mm.insert(p, x)</tt> inserts |
| <tt>x</tt> into <tt>mm</tt> with <tt>p</tt> as a hint as |
| to where it should go. Table 69 claims that the execution time is |
| amortized constant if the insert winds up taking place adjacent to |
| <tt>p</tt>, but does not say when, if ever, this is guaranteed to |
| happen. All it says it that <tt>p</tt> is a hint as to where to |
| insert. |
| </p> |
| <p> |
| The question is whether there is any guarantee about the relationship |
| between <tt>p</tt> and the insertion point, and, if so, what it |
| is. |
| </p> |
| <p> |
| I believe the present state is that there is no guarantee: The user |
| can supply <tt>p</tt>, and the implementation is allowed to |
| disregard it entirely. |
| </p> |
| |
| <p><b>Additional comments from Nathan:</b><br> |
| |
| The vote [in Redmond] was on whether to elaborately specify the use of |
| the hint, or to require behavior only if the value could be inserted |
| adjacent to the hint. I would like to ensure that we have a chance to |
| vote for a deterministic treatment: "before, if possible, otherwise |
| after, otherwise anywhere appropriate", as an alternative to the |
| proposed "before or after, if possible, otherwise [...]". |
| </p> |
| |
| <p><i>[Toronto: there was general agreement that this is a real defect: |
| when inserting an element x into a multiset that already contains |
| several copies of x, there is no way to know whether the hint will be |
| used. The proposed resolution was that the new element should always |
| be inserted as close to the hint as possible. So, for example, if |
| there is a subsequence of equivalent values, then providing a.begin() |
| as the hint means that the new element should be inserted before the |
| subsequence even if a.begin() is far away. JC van Winkel supplied |
| precise wording for this proposed resolution, and also for an |
| alternative resolution in which hints are only used when they are |
| adjacent to the insertion point.]</i></p> |
| |
| |
| <p><i>[Copenhagen: the LWG agreed to the original proposed resolution, |
| in which an insertion hint would be used even when it is far from the |
| insertion point. This was contingent on seeing a example |
| implementation showing that it is possible to implement this |
| requirement without loss of efficiency. John Potter provided such a |
| example implementation.]</i></p> |
| |
| |
| <p><i>[Redmond: The LWG was reluctant to adopt the proposal that |
| emerged from Copenhagen: it seemed excessively complicated, and went |
| beyond fixing the defect that we identified in Toronto. PJP provided |
| the new wording described in this issue. Nathan agrees that we |
| shouldn't adopt the more detailed semantics, and notes: "we know that |
| you can do it efficiently enough with a red-black tree, but there are |
| other (perhaps better) balanced tree techniques that might differ |
| enough to make the detailed semantics hard to satisfy."]</i></p> |
| |
| |
| <p><i>[Curaçao: Nathan should give us the alternative wording he |
| suggests so the LWG can decide between the two options.]</i></p> |
| |
| |
| <p><i>[Lillehammer: The LWG previously rejected the more detailed |
| semantics, because it seemed more loike a new feature than like |
| defect fixing. We're now more sympathetic to it, but we (especially |
| Bill) are still worried about performance. N1780 describes a naive |
| algorithm, but it's not clear whether there is a non-naive |
| implementation. Is it possible to implement this as efficently as |
| the current version of insert?]</i></p> |
| |
| |
| <p><i>[Post Lillehammer: |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">N1780</a> |
| updated in post meeting mailing with |
| feedback from Lillehammer with more information regarding performance. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Batavia: |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a> |
| accepted with minor wording changes in the proposed wording (reflected in the |
| proposed resolution below). Concerns about the performance of the algorithm |
| were satisfactorily met by |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a>. |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#371">371</a> already handles the stability of equal ranges |
| and so that part of the resolution from |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html">1780</a> |
| is no longer needed (or reflected in the proposed wording below). |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change the indicated rows of the "Associative container requirements" Table in |
| 23.1.4 [associative.reqmts] to: |
| </p> |
| |
| <p></p><center> |
| <table border="1"> |
| <caption>Associative container requirements</caption> |
| <tbody><tr><th>expression</th> <th>return type</th> |
| <th>assertion/note<br>pre/post-condition</th> |
| <th>complexity</th></tr> |
| <tr><td><tt>a_eq.insert(t)</tt></td> |
| <td><tt>iterator</tt></td> |
| <td> |
| inserts <tt>t</tt> and returns the iterator pointing to the newly inserted |
| element. <ins>If a range containing elements equivalent to <tt>t</tt> exists in |
| <tt>a_eq</tt>, <tt>t</tt> is inserted at the end of that range.</ins> |
| </td> |
| <td> |
| logarithmic |
| </td></tr> |
| <tr><td><tt>a.insert(p,t)</tt></td> |
| <td><tt>iterator</tt></td> |
| <td> |
| inserts <tt>t</tt> if and only if there is no element with key equivalent to the |
| key of <tt>t</tt> in containers with unique keys; always inserts <tt>t</tt> in containers |
| with equivalent keys. always returns the iterator pointing to the element with key |
| equivalent to the key of <tt>t</tt>. <del>iterator <tt>p</tt> is a hint pointing to where |
| the insert should start to search.</del> <ins><tt>t</tt> is inserted as close as possible |
| to the position just prior to <tt>p</tt>.</ins> |
| </td> |
| <td> |
| logarithmic in general, but amortized constant if <tt>t</tt> is inserted right <del>after</del> |
| <ins>before</ins> <tt>p</tt>. |
| </td></tr> |
| </tbody></table> |
| </center> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="234"></a>234. Typos in allocator definition</h3> |
| <p><b>Section:</b> 20.7.5.1 [allocator.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 2000-04-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.members">issues</a> in [allocator.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In paragraphs 12 and 13 the effects of <tt>construct()</tt> and |
| <tt>destruct()</tt> are described as returns but the functions actually |
| return <tt>void</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Substitute "Returns" by "Effect".</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="235"></a>235. No specification of default ctor for reverse_iterator</h3> |
| <p><b>Section:</b> 24.4.1.1 [reverse.iterator] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 2000-04-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The declaration of <tt>reverse_iterator</tt> lists a default |
| constructor. However, no specification is given what this constructor |
| should do.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 24.4.1.3.1 [reverse.iter.cons] add the following |
| paragraph:</p> |
| <blockquote> |
| <p><tt>reverse_iterator()</tt></p> |
| |
| <p>Default initializes <tt>current</tt>. Iterator operations |
| applied to the resulting iterator have defined behavior if and |
| only if the corresponding operations are defined on a default |
| constructed iterator of type <tt>Iterator</tt>.</p> |
| </blockquote> |
| <p><i>[pre-Copenhagen: Dietmar provide wording for proposed |
| resolution.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="237"></a>237. Undefined expression in complexity specification</h3> |
| <p><b>Section:</b> 23.2.2.1 [deque.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 2000-04-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#deque.cons">issues</a> in [deque.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The complexity specification in paragraph 6 says that the complexity |
| is linear in <tt>first - last</tt>. Even if <tt>operator-()</tt> is |
| defined on iterators this term is in general undefined because it |
| would have to be <tt>last - first</tt>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change paragraph 6 from</p> |
| <blockquote><p>Linear in <i>first - last</i>.</p></blockquote> |
| <p>to become</p> |
| <blockquote><p>Linear in <i>distance(first, last)</i>.</p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="238"></a>238. Contradictory results of stringbuf initialization.</h3> |
| <p><b>Section:</b> 27.7.1.1 [stringbuf.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dietmar Kühl <b>Date:</b> 2000-05-11</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 27.7.1.1 paragraph 4 the results of calling the constructor of |
| 'basic_stringbuf' are said to be <tt>str() == str</tt>. This is fine |
| that far but consider this code:</p> |
| |
| <pre> std::basic_stringbuf<char> sbuf("hello, world", std::ios_base::openmode(0)); |
| std::cout << "'" << sbuf.str() << "'\n"; |
| </pre> |
| |
| <p>Paragraph 3 of 27.7.1.1 basically says that in this case neither |
| the output sequence nor the input sequence is initialized and |
| paragraph 2 of 27.7.1.2 basically says that <tt>str()</tt> either |
| returns the input or the output sequence. None of them is initialized, |
| ie. both are empty, in which case the return from <tt>str()</tt> is |
| defined to be <tt>basic_string<cT>()</tt>.</p> |
| |
| <p>However, probably only test cases in some testsuites will detect this |
| "problem"...</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 27.7.1.1 paragraph 4.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>We could fix 27.7.1.1 paragraph 4, but there would be no point. If |
| we fixed it, it would say just the same thing as text that's already |
| in the standard.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="239"></a>239. Complexity of unique() and/or unique_copy incorrect</h3> |
| <p><b>Section:</b> 25.2.9 [alg.unique] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 2000-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.unique">issues</a> in [alg.unique].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The complexity of unique and unique_copy are inconsistent with each |
| other and inconsistent with the implementations. The standard |
| specifies:</p> |
| |
| <p>for unique():</p> |
| |
| <blockquote><p>-3- Complexity: If the range (last - first) is not empty, exactly |
| (last - first) - 1 applications of the corresponding predicate, otherwise |
| no applications of the predicate.</p></blockquote> |
| |
| <p>for unique_copy():</p> |
| |
| <blockquote><p>-7- Complexity: Exactly last - first applications of the corresponding |
| predicate.</p></blockquote> |
| |
| <p> |
| The implementations do it the other way round: unique() applies the |
| predicate last-first times and unique_copy() applies it last-first-1 |
| times.</p> |
| |
| <p>As both algorithms use the predicate for pair-wise comparison of |
| sequence elements I don't see a justification for unique_copy() |
| applying the predicate last-first times, especially since it is not |
| specified to which pair in the sequence the predicate is applied |
| twice.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change both complexity sections in 25.2.9 [alg.unique] to:</p> |
| |
| <blockquote><p>Complexity: For nonempty ranges, exactly last - first - 1 |
| applications of the corresponding predicate.</p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="240"></a>240. Complexity of adjacent_find() is meaningless</h3> |
| <p><b>Section:</b> 25.1.8 [alg.adjacent.find] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 2000-05-15</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The complexity section of adjacent_find is defective:</p> |
| |
| <blockquote> |
| <pre>template <class ForwardIterator> |
| ForwardIterator adjacent_find(ForwardIterator first, ForwardIterator last |
| BinaryPredicate pred); |
| </pre> |
| |
| <p>-1- Returns: The first iterator i such that both i and i + 1 are in |
| the range [first, last) for which the following corresponding |
| conditions hold: *i == *(i + 1), pred(*i, *(i + 1)) != false. Returns |
| last if no such iterator is found.</p> |
| |
| <p>-2- Complexity: Exactly find(first, last, value) - first applications |
| of the corresponding predicate. |
| </p> |
| </blockquote> |
| |
| <p>In the Complexity section, it is not defined what "value" |
| is supposed to mean. My best guess is that "value" means an |
| object for which one of the conditions pred(*i,value) or |
| pred(value,*i) is true, where i is the iterator defined in the Returns |
| section. However, the value type of the input sequence need not be |
| equality-comparable and for this reason the term find(first, last, |
| value) - first is meaningless.</p> |
| |
| <p>A term such as find_if(first, last, bind2nd(pred,*i)) - first or |
| find_if(first, last, bind1st(pred,*i)) - first might come closer to |
| the intended specification. Binders can only be applied to function |
| objects that have the function call operator declared const, which is |
| not required of predicates because they can have non-const data |
| members. For this reason, a specification using a binder could only be |
| an "as-if" specification.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the complexity section in 25.1.8 [alg.adjacent.find] to:</p> |
| <blockquote><p> |
| For a nonempty range, exactly <tt>min((<i>i</i> - <i>first</i>) + 1, |
| (<i>last</i> - <i>first</i>) - 1)</tt> applications of the |
| corresponding predicate, where <i>i</i> is <tt>adjacent_find</tt>'s |
| return value. |
| </p></blockquote> |
| |
| <p><i>[Copenhagen: the original resolution specified an upper |
| bound. The LWG preferred an exact count.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="241"></a>241. Does unique_copy() require CopyConstructible and Assignable?</h3> |
| <p><b>Section:</b> 25.2.9 [alg.unique] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 2000-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.unique">issues</a> in [alg.unique].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>Some popular implementations of unique_copy() create temporary |
| copies of values in the input sequence, at least if the input iterator |
| is a pointer. Such an implementation is built on the assumption that |
| the value type is CopyConstructible and Assignable.</p> |
| |
| <p>It is common practice in the standard that algorithms explicitly |
| specify any additional requirements that they impose on any of the |
| types used by the algorithm. An example of an algorithm that creates |
| temporary copies and correctly specifies the additional requirements |
| is accumulate(), 26.4.1 [rand.req].</p> |
| |
| <p>Since the specifications of unique() and unique_copy() do not |
| require CopyConstructible and Assignable of the InputIterator's value |
| type the above mentioned implementations are not standard-compliant. I |
| cannot judge whether this is a defect in the standard or a defect in |
| the implementations.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.2.8 change:</p> |
| |
| <blockquote><p> |
| -4- Requires: The ranges [first, last) and [result, result+(last-first)) |
| shall not overlap. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>-4- Requires: The ranges [first, last) and [result, |
| result+(last-first)) shall not overlap. The expression *result = |
| *first must be valid. If neither InputIterator nor OutputIterator |
| meets the requirements of forward iterator then the value type of |
| InputIterator must be copy constructible. Otherwise copy |
| constructible is not required. </p> |
| </blockquote> |
| |
| <p><i>[Redmond: the original proposed resolution didn't impose an |
| explicit requirement that the iterator's value type must be copy |
| constructible, on the grounds that an input iterator's value type must |
| always be copy constructible. Not everyone in the LWG thought that |
| this requirement was clear from table 72. It has been suggested that |
| it might be possible to implement <tt>unique_copy</tt> without |
| requiring assignability, although current implementations do impose |
| that requirement. Howard provided new wording.]</i></p> |
| |
| |
| <p><i>[ |
| Curaçao: The LWG changed the PR editorially to specify |
| "neither...nor...meet..." as clearer than |
| "both...and...do not meet...". Change believed to be so |
| minor as not to require re-review. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="242"></a>242. Side effects of function objects</h3> |
| <p><b>Section:</b> 25.2.4 [alg.transform], 26.4 [rand] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Angelika Langer <b>Date:</b> 2000-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.transform">issues</a> in [alg.transform].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The algorithms transform(), accumulate(), inner_product(), |
| partial_sum(), and adjacent_difference() require that the function |
| object supplied to them shall not have any side effects.</p> |
| |
| <p>The standard defines a side effect in 1.9 [intro.execution] as:</p> |
| <blockquote><p>-7- Accessing an object designated by a volatile lvalue (basic.lval), |
| modifying an object, calling a library I/O function, or calling a function |
| that does any of those operations are all side effects, which are changes |
| in the state of the execution environment.</p></blockquote> |
| |
| <p>As a consequence, the function call operator of a function object supplied |
| to any of the algorithms listed above cannot modify data members, cannot |
| invoke any function that has a side effect, and cannot even create and |
| modify temporary objects. It is difficult to imagine a function object |
| that is still useful under these severe limitations. For instance, any |
| non-trivial transformator supplied to transform() might involve creation |
| and modification of temporaries, which is prohibited according to the current |
| wording of the standard.</p> |
| |
| <p>On the other hand, popular implementations of these algorithms exhibit |
| uniform and predictable behavior when invoked with a side-effect-producing |
| function objects. It looks like the strong requirement is not needed for |
| efficient implementation of these algorithms.</p> |
| |
| <p>The requirement of side-effect-free function objects could be |
| replaced by a more relaxed basic requirement (which would hold for all |
| function objects supplied to any algorithm in the standard library):</p> |
| <blockquote><p>A function objects supplied to an algorithm shall not invalidate |
| any iterator or sequence that is used by the algorithm. Invalidation of |
| the sequence includes destruction of the sorting order if the algorithm |
| relies on the sorting order (see section 25.3 - Sorting and related operations |
| [lib.alg.sorting]).</p></blockquote> |
| |
| <p>I can't judge whether it is intended that the function objects supplied |
| to transform(), accumulate(), inner_product(), partial_sum(), or adjacent_difference() |
| shall not modify sequence elements through dereferenced iterators.</p> |
| |
| <p>It is debatable whether this issue is a defect or a change request. |
| Since the consequences for user-supplied function objects are drastic and |
| limit the usefulness of the algorithms significantly I would consider it |
| a defect.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>Things to notice about these changes:</i></p> |
| |
| <ol> |
| <li> <i>The fully-closed ("[]" as opposed to half-closed "[)" ranges |
| are intentional. we want to prevent side-effects from |
| invalidating the end iterators.</i></li> |
| |
| <li> <i>That has the unintentional side-effect of prohibiting |
| modification of the end element as a side-effect. This could |
| conceivably be significant in some cases.</i></li> |
| |
| <li> <i>The wording also prevents side-effects from modifying elements |
| of the output sequence. I can't imagine why anyone would want |
| to do this, but it is arguably a restriction that implementors |
| don't need to place on users.</i></li> |
| |
| <li> <i>Lifting the restrictions imposed in #2 and #3 above is possible |
| and simple, but would require more verbiage.</i></li> |
| </ol> |
| |
| <p>Change 25.2.3/2 from:</p> |
| |
| <blockquote><p> |
| -2- Requires: op and binary_op shall not have any side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -2- Requires: in the ranges [first1, last1], [first2, first2 + |
| (last1 - first1)] and [result, result + (last1- first1)], op and |
| binary_op shall neither modify elements nor invalidate iterators or |
| subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </p></blockquote> |
| |
| |
| <p>Change 25.2.3/2 from:</p> |
| |
| <blockquote><p> |
| -2- Requires: op and binary_op shall not have any side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -2- Requires: op and binary_op shall not invalidate iterators or |
| subranges, or modify elements in the ranges [first1, last1], |
| [first2, first2 + (last1 - first1)], and [result, result + (last1 |
| - first1)]. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </p></blockquote> |
| |
| |
| <p>Change 26.4.1/2 from:</p> |
| |
| <blockquote><p> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. binary_op shall not cause side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable |
| (lib.container.requirements) types. In the range [first, last], |
| binary_op shall neither modify elements nor invalidate iterators |
| or subranges. |
| [Footnote: The use of a fully closed range is intentional --end footnote] |
| </p></blockquote> |
| |
| <p>Change 26.4.2/2 from:</p> |
| |
| <blockquote><p> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. binary_op1 and binary_op2 shall not cause side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -2- Requires: T must meet the requirements of CopyConstructible |
| (lib.copyconstructible) and Assignable (lib.container.requirements) |
| types. In the ranges [first, last] and [first2, first2 + (last - |
| first)], binary_op1 and binary_op2 shall neither modify elements |
| nor invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </p></blockquote> |
| |
| |
| <p>Change 26.4.3/4 from:</p> |
| |
| <blockquote><p> |
| -4- Requires: binary_op is expected not to have any side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -4- Requires: In the ranges [first, last] and [result, result + |
| (last - first)], binary_op shall neither modify elements nor |
| invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </p></blockquote> |
| |
| <p>Change 26.4.4/2 from:</p> |
| |
| <blockquote><p> |
| -2- Requires: binary_op shall not have any side effects. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -2- Requires: In the ranges [first, last] and [result, result + |
| (last - first)], binary_op shall neither modify elements nor |
| invalidate iterators or subranges. |
| [Footnote: The use of fully closed ranges is intentional --end footnote] |
| </p></blockquote> |
| |
| <p><i>[Toronto: Dave Abrahams supplied wording.]</i></p> |
| |
| |
| <p><i>[Copenhagen: Proposed resolution was modified slightly. Matt |
| added footnotes pointing out that the use of closed ranges was |
| intentional.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="243"></a>243. <tt>get</tt> and <tt>getline</tt> when sentry reports failure</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>basic_istream<>::get(), and basic_istream<>::getline(), |
| are unclear with respect to the behavior and side-effects of the named |
| functions in case of an error.</p> |
| |
| <p>27.6.1.3, p1 states that "... If the sentry object returns |
| true, when converted to a value of type bool, the function endeavors |
| to obtain the requested input..." It is not clear from this (or |
| the rest of the paragraph) what precisely the behavior should be when |
| the sentry ctor exits by throwing an exception or when the sentry |
| object returns false. In particular, what is the number of characters |
| extracted that gcount() returns supposed to be?</p> |
| |
| <p>27.6.1.3 p8 and p19 say about the effects of get() and getline(): |
| "... In any case, it then stores a null character (using |
| charT()) into the next successive location of the array." Is not |
| clear whether this sentence applies if either of the conditions above |
| holds (i.e., when sentry fails).</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to 27.6.1.3, p1 after the sentence</p> |
| |
| <blockquote><p> |
| "... If the sentry object returns true, when converted to a value of |
| type bool, the function endeavors to obtain the requested input." |
| </p></blockquote> |
| |
| <p>the following</p> |
| |
| |
| <blockquote><p> |
| "Otherwise, if the sentry constructor exits by throwing an exception or |
| if the sentry object returns false, when converted to a value of type |
| bool, the function returns without attempting to obtain any input. In |
| either case the number of extracted characters is set to 0; unformatted |
| input functions taking a character array of non-zero size as an argument |
| shall also store a null character (using charT()) in the first location |
| of the array." |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Although the general philosophy of the input functions is that the |
| argument should not be modified upon failure, <tt>getline</tt> |
| historically added a terminating null unconditionally. Most |
| implementations still do that. Earlier versions of the draft standard |
| had language that made this an unambiguous requirement; those words |
| were moved to a place where their context made them less clear. See |
| Jerry Schwarz's message c++std-lib-7618.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="247"></a>247. <tt>vector</tt>, <tt>deque::insert</tt> complexity</h3> |
| <p><b>Section:</b> 23.2.6.4 [vector.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Lisa Lippincott <b>Date:</b> 2000-06-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.modifiers">issues</a> in [vector.modifiers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 2 of 23.2.6.4 [vector.modifiers] describes the complexity |
| of <tt>vector::insert</tt>:</p> |
| |
| <blockquote><p> |
| Complexity: If first and last are forward iterators, bidirectional |
| iterators, or random access iterators, the complexity is linear in |
| the number of elements in the range [first, last) plus the distance |
| to the end of the vector. If they are input iterators, the complexity |
| is proportional to the number of elements in the range [first, last) |
| times the distance to the end of the vector. |
| </p></blockquote> |
| |
| <p>First, this fails to address the non-iterator forms of |
| <tt>insert</tt>.</p> |
| |
| <p>Second, the complexity for input iterators misses an edge case -- |
| it requires that an arbitrary number of elements can be added at |
| the end of a <tt>vector</tt> in constant time.</p> |
| |
| <p>I looked to see if <tt>deque</tt> had a similar problem, and was |
| surprised to find that <tt>deque</tt> places no requirement on the |
| complexity of inserting multiple elements (23.2.2.3 [deque.modifiers], |
| paragraph 3):</p> |
| |
| <blockquote><p> |
| Complexity: In the worst case, inserting a single element into a |
| deque takes time linear in the minimum of the distance from the |
| insertion point to the beginning of the deque and the distance |
| from the insertion point to the end of the deque. Inserting a |
| single element either at the beginning or end of a deque always |
| takes constant time and causes a single call to the copy constructor |
| of T. |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change Paragraph 2 of 23.2.6.4 [vector.modifiers] to</p> |
| <blockquote><p> |
| Complexity: The complexity is linear in the number of elements |
| inserted plus the distance to the end of the vector. |
| </p></blockquote> |
| |
| <p><i>[For input iterators, one may achieve this complexity by first |
| inserting at the end of the <tt>vector</tt>, and then using |
| <tt>rotate</tt>.]</i></p> |
| |
| |
| <p>Change 23.2.2.3 [deque.modifiers], paragraph 3, to:</p> |
| |
| <blockquote><p> |
| Complexity: The complexity is linear in the number of elements |
| inserted plus the shorter of the distances to the beginning and |
| end of the deque. Inserting a single element at either the |
| beginning or the end of a deque causes a single call to the copy |
| constructor of T. |
| </p></blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This is a real defect, and proposed resolution fixes it: some |
| complexities aren't specified that should be. This proposed |
| resolution does constrain deque implementations (it rules out the |
| most naive possible implementations), but the LWG doesn't see a |
| reason to permit that implementation.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="248"></a>248. time_get fails to set eofbit</h3> |
| <p><b>Section:</b> 22.2.5 [category.time] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-06-22</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>There is no requirement that any of time_get member functions set |
| ios::eofbit when they reach the end iterator while parsing their input. |
| Since members of both the num_get and money_get facets are required to |
| do so (22.2.2.1.2, and 22.2.6.1.2, respectively), time_get members |
| should follow the same requirement for consistency.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add paragraph 2 to section 22.2.5.1 with the following text:</p> |
| |
| <blockquote><p> |
| If the end iterator is reached during parsing by any of the get() |
| member functions, the member sets ios_base::eofbit in err. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Two alternative resolutions were proposed. The LWG chose this one |
| because it was more consistent with the way eof is described for other |
| input facets.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="250"></a>250. splicing invalidates iterators</h3> |
| <p><b>Section:</b> 23.2.4.4 [list.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Brian Parker <b>Date:</b> 2000-07-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.ops">issues</a> in [list.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 23.2.4.4 [list.ops] states that |
| </p> |
| <pre> void splice(iterator position, list<T, Allocator>& x); |
| </pre> |
| <p> |
| <i>invalidates</i> all iterators and references to list <tt>x</tt>. |
| </p> |
| |
| <p> |
| This is unnecessary and defeats an important feature of splice. In |
| fact, the SGI STL guarantees that iterators to <tt>x</tt> remain valid |
| after <tt>splice</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add a footnote to 23.2.4.4 [list.ops], paragraph 1:</p> |
| <blockquote><p> |
| [<i>Footnote:</i> As specified in [default.con.req], paragraphs |
| 4-5, the semantics described in this clause applies only to the case |
| where allocators compare equal. --end footnote] |
| </p></blockquote> |
| |
| <p>In 23.2.4.4 [list.ops], replace paragraph 4 with:</p> |
| <blockquote><p> |
| Effects: Inserts the contents of x before position and x becomes |
| empty. Pointers and references to the moved elements of x now refer to |
| those same elements but as members of *this. Iterators referring to the |
| moved elements will continue to refer to their elements, but they now |
| behave as iterators into *this, not into x. |
| </p></blockquote> |
| |
| <p>In 23.2.4.4 [list.ops], replace paragraph 7 with:</p> |
| <blockquote><p> |
| Effects: Inserts an element pointed to by i from list x before |
| position and removes the element from x. The result is unchanged if |
| position == i or position == ++i. Pointers and references to *i continue |
| to refer to this same element but as a member of *this. Iterators to *i |
| (including i itself) continue to refer to the same element, but now |
| behave as iterators into *this, not into x. |
| </p></blockquote> |
| |
| <p>In 23.2.4.4 [list.ops], replace paragraph 12 with:</p> |
| <blockquote><p> |
| Requires: [first, last) is a valid range in x. The result is |
| undefined if position is an iterator in the range [first, last). |
| Pointers and references to the moved elements of x now refer to those |
| same elements but as members of *this. Iterators referring to the moved |
| elements will continue to refer to their elements, but they now behave as |
| iterators into *this, not into x. |
| </p></blockquote> |
| |
| <p><i>[pre-Copenhagen: Howard provided wording.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution said that iterators and references |
| would remain "valid". The new proposed resolution clarifies what that |
| means. Note that this only applies to the case of equal allocators. |
| From [default.con.req] paragraph 4, the behavior of list when |
| allocators compare nonequal is outside the scope of the standard.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="251"></a>251. basic_stringbuf missing allocator_type</h3> |
| <p><b>Section:</b> 27.7.1 [stringbuf] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-07-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The synopsis for the template class <tt>basic_stringbuf</tt> |
| doesn't list a typedef for the template parameter |
| <tt>Allocator</tt>. This makes it impossible to determine the type of |
| the allocator at compile time. It's also inconsistent with all other |
| template classes in the library that do provide a typedef for the |
| <tt>Allocator</tt> parameter.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to the synopses of the class templates basic_stringbuf (27.7.1), |
| basic_istringstream (27.7.2), basic_ostringstream (27.7.3), and |
| basic_stringstream (27.7.4) the typedef:</p> |
| <pre> typedef Allocator allocator_type; |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="252"></a>252. missing casts/C-style casts used in iostreams</h3> |
| <p><b>Section:</b> 27.7 [string.streams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-07-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.streams">issues</a> in [string.streams].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.7.2.2, p1 uses a C-style cast rather than the more appropriate |
| const_cast<> in the Returns clause for basic_istringstream<>::rdbuf(). |
| The same C-style cast is being used in 27.7.3.2, p1, D.7.2.2, p1, and |
| D.7.3.2, p1, and perhaps elsewhere. 27.7.6, p1 and D.7.2.2, p1 are missing |
| the cast altogether.</p> |
| |
| <p>C-style casts have not been deprecated, so the first part of this |
| issue is stylistic rather than a matter of correctness.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.7.2.2, p1 replace </p> |
| <pre> -1- Returns: (basic_stringbuf<charT,traits,Allocator>*)&sb.</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| |
| <p>In 27.7.3.2, p1 replace</p> |
| <pre> -1- Returns: (basic_stringbuf<charT,traits,Allocator>*)&sb.</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| <p>In 27.7.6, p1, replace</p> |
| <pre> -1- Returns: &sb</pre> |
| |
| <p>with</p> |
| <pre> -1- Returns: const_cast<basic_stringbuf<charT,traits,Allocator>*>(&sb).</pre> |
| |
| <p>In D.7.2.2, p1 replace</p> |
| <pre> -2- Returns: &sb. </pre> |
| |
| <p>with</p> |
| <pre> -2- Returns: const_cast<strstreambuf*>(&sb).</pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="253"></a>253. valarray helper functions are almost entirely useless</h3> |
| <p><b>Section:</b> 26.5.2.1 [valarray.cons], 26.5.2.2 [valarray.assign] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Robert Klarer <b>Date:</b> 2000-07-31</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#valarray.cons">active issues</a> in [valarray.cons].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#valarray.cons">issues</a> in [valarray.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>This discussion is adapted from message c++std-lib-7056 posted |
| November 11, 1999. I don't think that anyone can reasonably claim |
| that the problem described below is NAD.</p> |
| |
| <p>These valarray constructors can never be called:</p> |
| |
| <pre> template <class T> |
| valarray<T>::valarray(const slice_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const gslice_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const mask_array<T> &); |
| template <class T> |
| valarray<T>::valarray(const indirect_array<T> &); |
| </pre> |
| |
| <p>Similarly, these valarray assignment operators cannot be |
| called:</p> |
| |
| <pre> template <class T> |
| valarray<T> valarray<T>::operator=(const slice_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const gslice_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const mask_array<T> &); |
| template <class T> |
| valarray<T> valarray<T>::operator=(const indirect_array<T> &); |
| </pre> |
| |
| <p>Please consider the following example:</p> |
| |
| <pre> #include <valarray> |
| using namespace std; |
| |
| int main() |
| { |
| valarray<double> va1(12); |
| valarray<double> va2(va1[slice(1,4,3)]); // line 1 |
| } |
| </pre> |
| |
| |
| <p>Since the valarray va1 is non-const, the result of the sub-expression |
| va1[slice(1,4,3)] at line 1 is an rvalue of type const |
| std::slice_array<double>. This slice_array rvalue is then used to |
| construct va2. The constructor that is used to construct va2 is |
| declared like this:</p> |
| |
| <pre> template <class T> |
| valarray<T>::valarray(const slice_array<T> &); |
| </pre> |
| |
| <p>Notice the constructor's const reference parameter. When the |
| constructor is called, a slice_array must be bound to this reference. |
| The rules for binding an rvalue to a const reference are in 8.5.3, |
| paragraph 5 (see also 13.3.3.1.4). Specifically, paragraph 5 |
| indicates that a second slice_array rvalue is constructed (in this |
| case copy-constructed) from the first one; it is this second rvalue |
| that is bound to the reference parameter. Paragraph 5 also requires |
| that the constructor that is used for this purpose be callable, |
| regardless of whether the second rvalue is elided. The |
| copy-constructor in this case is not callable, however, because it is |
| private. Therefore, the compiler should report an error.</p> |
| |
| <p>Since slice_arrays are always rvalues, the valarray constructor that has a |
| parameter of type const slice_array<T> & can never be called. The |
| same reasoning applies to the three other constructors and the four |
| assignment operators that are listed at the beginning of this post. |
| Furthermore, since these functions cannot be called, the valarray helper |
| classes are almost entirely useless.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>slice_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the slice_array class template definition in 26.5.5 [template.slice.array] </li> |
| <li> remove paragraph 3 of 26.5.5 [template.slice.array]</li> |
| <li> remove the copy constructor declaration from [cons.slice.arr]</li> |
| <li> change paragraph 1 of [cons.slice.arr] to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.5.1 [slice.arr.assign]</li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.5.1 [slice.arr.assign] to "These assignment operators have"</li> |
| </ul> |
| |
| <p>gslice_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the gslice_array class template definition in 26.5.7 [template.gslice.array] </li> |
| <li> remove the note in paragraph 3 of 26.5.7 [template.gslice.array]</li> |
| <li> remove the copy constructor declaration from [gslice.array.cons]</li> |
| <li> change paragraph 1 of [gslice.array.cons] to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.7.1 [gslice.array.assign]</li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.7.1 [gslice.array.assign] to "These assignment operators have"</li> |
| </ul> |
| |
| <p>mask_array:</p> |
| <ul> |
| <li> Make the copy constructor and copy-assignment operator declarations |
| public in the mask_array class template definition in 26.5.8 [template.mask.array] </li> |
| <li> remove the note in paragraph 2 of 26.5.8 [template.mask.array]</li> |
| <li> remove the copy constructor declaration from [mask.array.cons]</li> |
| <li> change paragraph 1 of [mask.array.cons] to read "This constructor is declared |
| to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.8.1 [mask.array.assign]</li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.8.1 [mask.array.assign] to "These assignment operators have"</li> |
| </ul> |
| |
| <p>indirect_array:</p> |
| <ul> |
| <li>Make the copy constructor and copy-assignment operator declarations |
| public in the indirect_array class definition in 26.5.9 [template.indirect.array]</li> |
| <li> remove the note in paragraph 2 of 26.5.9 [template.indirect.array]</li> |
| <li> remove the copy constructor declaration from [indirect.array.cons]</li> |
| <li> change the descriptive text in [indirect.array.cons] to read "This constructor is |
| declared to be private. This constructor need not be defined."</li> |
| <li> remove the first sentence of paragraph 1 of 26.5.9.1 [indirect.array.assign]</li> |
| <li> Change the first three words of the second sentence of paragraph 1 of |
| 26.5.9.1 [indirect.array.assign] to "These assignment operators have"</li> |
| </ul> |
| <p><i>[Proposed resolution was modified in Santa Cruz: explicitly make |
| copy constructor and copy assignment operators public, instead of |
| removing them.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Keeping the valarray constructors private is untenable. Merely |
| making valarray a friend of the helper classes isn't good enough, |
| because access to the copy constructor is checked in the user's |
| environment.</p> |
| |
| <p>Making the assignment operator public is not strictly necessary to |
| solve this problem. A majority of the LWG <i>(straw poll: 13-4)</i> |
| believed we should make the assignment operators public, in addition |
| to the copy constructors, for reasons of symmetry and user |
| expectation.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="254"></a>254. Exception types in clause 19 are constructed from <tt>std::string</tt></h3> |
| <p><b>Section:</b> 19.1 [std.exceptions], 27.4.2.1.1 [ios::failure] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2000-08-01</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Many of the standard exception types which implementations are |
| required to throw are constructed with a const std::string& |
| parameter. For example: |
| </p> |
| |
| <pre> 19.1.5 Class out_of_range [lib.out.of.range] |
| namespace std { |
| class out_of_range : public logic_error { |
| public: |
| explicit out_of_range(const string& what_arg); |
| }; |
| } |
| |
| 1 The class out_of_range defines the type of objects thrown as excep- |
| tions to report an argument value not in its expected range. |
| |
| out_of_range(const string& what_arg); |
| |
| Effects: |
| Constructs an object of class out_of_range. |
| Postcondition: |
| strcmp(what(), what_arg.c_str()) == 0. |
| </pre> |
| |
| <p> |
| There are at least two problems with this: |
| </p> |
| <ol> |
| <li>A program which is low on memory may end up throwing |
| std::bad_alloc instead of out_of_range because memory runs out while |
| constructing the exception object.</li> |
| <li>An obvious implementation which stores a std::string data member |
| may end up invoking terminate() during exception unwinding because the |
| exception object allocates memory (or rather fails to) as it is being |
| copied.</li> |
| </ol> |
| |
| <p> |
| There may be no cure for (1) other than changing the interface to |
| out_of_range, though one could reasonably argue that (1) is not a |
| defect. Personally I don't care that much if out-of-memory is reported |
| when I only have 20 bytes left, in the case when out_of_range would |
| have been reported. People who use exception-specifications might care |
| a lot, though. |
| </p> |
| |
| <p> |
| There is a cure for (2), but it isn't completely obvious. I think a |
| note for implementors should be made in the standard. Avoiding |
| possible termination in this case shouldn't be left up to chance. The |
| cure is to use a reference-counted "string" implementation |
| in the exception object. I am not necessarily referring to a |
| std::string here; any simple reference-counting scheme for a NTBS |
| would do. |
| </p> |
| |
| <p><b>Further discussion, in email:</b></p> |
| |
| <p> |
| ...I'm not so concerned about (1). After all, a library implementation |
| can add const char* constructors as an extension, and users don't |
| <i>need</i> to avail themselves of the standard exceptions, though this is |
| a lame position to be forced into. FWIW, std::exception and |
| std::bad_alloc don't require a temporary basic_string. |
| </p> |
| |
| <p> |
| ...I don't think the fixed-size buffer is a solution to the problem, |
| strictly speaking, because you can't satisfy the postcondition |
| <br> |
| <tt> strcmp(what(), what_arg.c_str()) == 0</tt> |
| <br> |
| For all values of what_arg (i.e. very long values). That means that |
| the only truly conforming solution requires a dynamic allocation. |
| </p> |
| |
| <p><b>Further discussion, from Redmond:</b></p> |
| |
| <p>The most important progress we made at the Redmond meeting was |
| realizing that there are two separable issues here: the const |
| string& constructor, and the copy constructor. If a user writes |
| something like <tt>throw std::out_of_range("foo")</tt>, the const |
| string& constructor is invoked before anything gets thrown. The |
| copy constructor is potentially invoked during stack unwinding.</p> |
| |
| <p>The copy constructor is a more serious problem, becuase failure |
| during stack unwinding invokes <tt>terminate</tt>. The copy |
| constructor must be nothrow. <i>Curaçao: Howard thinks this |
| requirement may already be present.</i></p> |
| |
| <p>The fundamental problem is that it's difficult to get the nothrow |
| requirement to work well with the requirement that the exception |
| objects store a string of unbounded size, particularly if you also try |
| to make the const string& constructor nothrow. Options discussed |
| include:</p> |
| |
| <ul> |
| <li>Limit the size of a string that exception objects are required to |
| throw: change the postconditions of 19.1.2 [domain.error] paragraph 3 |
| and 19.1.6 [runtime.error] paragraph 3 to something like this: |
| "strncmp(what(), what_arg._str(), N) == 0, where N is an |
| implementation defined constant no smaller than 256".</li> |
| <li>Allow the const string& constructor to throw, but not the |
| copy constructor. It's the implementor's responsibility to get it |
| right. (An implementor might use a simple refcount class.)</li> |
| <li>Compromise between the two: an implementation is not allowed to |
| throw if the string's length is less than some N, but, if it doesn't |
| throw, the string must compare equal to the argument.</li> |
| <li>Add a new constructor that takes a const char*</li> |
| </ul> |
| |
| <p>(Not all of these options are mutually exclusive.)</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change 19.1.1 [logic.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class logic_error : public exception { |
| public: |
| explicit logic_error(const string& <i>what_arg</i>); |
| <ins>explicit logic_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>logic_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>logic_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.2 [domain.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class domain_error : public logic_error { |
| public: |
| explicit domain_error(const string& <i>what_arg</i>); |
| <ins>explicit domain_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>domain_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>domain_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Change 19.1.3 [invalid.argument] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class invalid_argument : public logic_error { |
| public: |
| explicit invalid_argument(const string& <i>what_arg</i>); |
| <ins>explicit invalid_argument(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>invalid_argument(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>invalid_argument</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.4 [length.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class length_error : public logic_error { |
| public: |
| explicit length_error(const string& <i>what_arg</i>); |
| <ins>explicit length_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>length_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>length_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.5 [out.of.range] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class out_of_range : public logic_error { |
| public: |
| explicit out_of_range(const string& <i>what_arg</i>); |
| <ins>explicit out_of_range(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>out_of_range(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>out_of_range</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.6 [runtime.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class runtime_error : public exception { |
| public: |
| explicit runtime_error(const string& <i>what_arg</i>); |
| <ins>explicit runtime_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>runtime_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>runtime_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.7 [range.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class range_error : public runtime_error { |
| public: |
| explicit range_error(const string& <i>what_arg</i>); |
| <ins>explicit range_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>range_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>range_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.8 [overflow.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class overflow_error : public runtime_error { |
| public: |
| explicit overflow_error(const string& <i>what_arg</i>); |
| <ins>explicit overflow_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>overflow_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>overflow_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 19.1.9 [underflow.error] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class underflow_error : public runtime_error { |
| public: |
| explicit underflow_error(const string& <i>what_arg</i>); |
| <ins>explicit underflow_error(const char* <i>what_arg</i>);</ins> |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>underflow_error(const char* <i>what_arg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>underflow_error</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>what_arg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 27.4.2.1.1 [ios::failure] |
| </p> |
| |
| <blockquote> |
| <pre>namespace std { |
| class ios_base::failure : public exception { |
| public: |
| explicit failure(const string& <i>msg</i>); |
| <ins>explicit failure(const char* <i>msg</i>);</ins> |
| virtual const char* what() const throw(); |
| }; |
| } |
| </pre> |
| <p>...</p> |
| <p> |
| <ins><tt>failure(const char* <i>msg</i>);</tt></ins> |
| </p> |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Constructs an object of class <tt>failure</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Postcondition:</i> <tt>strcmp(what(), <i>msg</i>) == 0</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| |
| <p>Throwing a bad_alloc while trying to construct a message for another |
| exception-derived class is not necessarily a bad thing. And the |
| bad_alloc constructor already has a no throw spec on it (18.4.2.1).</p> |
| |
| <p><b>Future:</b></p> |
| |
| <p>All involved would like to see const char* constructors added, but |
| this should probably be done for C++0X as opposed to a DR.</p> |
| |
| <p>I believe the no throw specs currently decorating these functions |
| could be improved by some kind of static no throw spec checking |
| mechanism (in a future C++ language). As they stand, the copy |
| constructors might fail via a call to unexpected. I think what is |
| intended here is that the copy constructors can't fail.</p> |
| |
| <p><i>[Pre-Sydney: reopened at the request of Howard Hinnant. |
| Post-Redmond: James Kanze noticed that the copy constructors of |
| exception-derived classes do not have nothrow clauses. Those |
| classes have no copy constructors declared, meaning the |
| compiler-generated implicit copy constructors are used, and those |
| compiler-generated constructors might in principle throw anything.]</i></p> |
| |
| |
| <p><i>[ |
| Batavia: Merged copy constructor and assignment operator spec into <tt>exception</tt> |
| and added <tt>ios::failure</tt> into the proposed resolution. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Oxford: The proposed resolution simply addresses the issue of constructing |
| the exception objects with <tt>const char*</tt> and string literals without |
| the need to explicit include or construct a <tt>std::string</tt>. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="256"></a>256. typo in 27.4.4.2, p17: copy_event does not exist</h3> |
| <p><b>Section:</b> 27.4.4.2 [basic.ios.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-08-21</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.ios.members">active issues</a> in [basic.ios.members].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.ios.members">issues</a> in [basic.ios.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 27.4.4.2, p17 says |
| </p> |
| |
| <blockquote><p> |
| -17- Before copying any parts of rhs, calls each registered callback |
| pair (fn,index) as (*fn)(erase_event,*this,index). After all parts but |
| exceptions() have been replaced, calls each callback pair that was |
| copied from rhs as (*fn)(copy_event,*this,index). |
| </p></blockquote> |
| |
| <p> |
| The name copy_event isn't defined anywhere. The intended name was |
| copyfmt_event. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace copy_event with copyfmt_event in the named paragraph.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="258"></a>258. Missing allocator requirement</h3> |
| <p><b>Section:</b> 20.1.2 [allocator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2000-08-22</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| From lib-7752: |
| </p> |
| |
| <p> |
| I've been assuming (and probably everyone else has been assuming) that |
| allocator instances have a particular property, and I don't think that |
| property can be deduced from anything in Table 32. |
| </p> |
| |
| <p> |
| I think we have to assume that allocator type conversion is a |
| homomorphism. That is, if x1 and x2 are of type X, where |
| X::value_type is T, and if type Y is X::template |
| rebind<U>::other, then Y(x1) == Y(x2) if and only if x1 == x2. |
| </p> |
| |
| <p> |
| Further discussion: Howard Hinnant writes, in lib-7757: |
| </p> |
| |
| <p> |
| I think I can prove that this is not provable by Table 32. And I agree |
| it needs to be true except for the "and only if". If x1 != x2, I see no |
| reason why it can't be true that Y(x1) == Y(x2). Admittedly I can't |
| think of a practical instance where this would happen, or be valuable. |
| But I also don't see a need to add that extra restriction. I think we |
| only need: |
| </p> |
| |
| <blockquote><p> |
| if (x1 == x2) then Y(x1) == Y(x2) |
| </p></blockquote> |
| |
| <p> |
| If we decide that == on allocators is transitive, then I think I can |
| prove the above. But I don't think == is necessarily transitive on |
| allocators. That is: |
| </p> |
| |
| <p> |
| Given x1 == x2 and x2 == x3, this does not mean x1 == x3. |
| </p> |
| |
| <p>Example:</p> |
| |
| <blockquote> |
| <p> |
| x1 can deallocate pointers from: x1, x2, x3 <br> |
| x2 can deallocate pointers from: x1, x2, x4 <br> |
| x3 can deallocate pointers from: x1, x3 <br> |
| x4 can deallocate pointers from: x2, x4 |
| </p> |
| |
| <p> |
| x1 == x2, and x2 == x4, but x1 != x4 |
| </p> |
| </blockquote> |
| <p><i>[Toronto: LWG members offered multiple opinions. One |
| opinion is that it should not be required that <tt>x1 == x2</tt> |
| implies <tt>Y(x1) == Y(x2)</tt>, and that it should not even be |
| required that <tt>X(x1) == x1</tt>. Another opinion is that |
| the second line from the bottom in table 32 already implies the |
| desired property. This issue should be considered in light of |
| other issues related to allocator instances.]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Accept proposed wording from |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2436.pdf">N2436</a> part 3. |
| </p> |
| |
| |
| <p><i>[Lillehammer: Same conclusion as before: this should be |
| considered as part of an allocator redesign, not solved on its own.]</i></p> |
| |
| |
| <p><i>[ |
| Batavia: An allocator redesign is not forthcoming and thus we fixed this one issue. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Toronto: Reopened at the request of the project editor (Pete) because the proposed |
| wording did not fit within the indicated table. The intent of the resolution remains |
| unchanged. Pablo to work with Pete on improved wording. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2387 for this issue which |
| was subsequently split out into a separate paper N2436 for the purposes of voting. |
| The resolution in N2436 addresses this issue. The LWG voted to accelerate this |
| issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="259"></a>259. <tt>basic_string::operator[]</tt> and const correctness</h3> |
| <p><b>Section:</b> 21.3.4 [string.capacity] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Chris Newton <b>Date:</b> 2000-08-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.capacity">issues</a> in [string.capacity].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <i>Paraphrased from a message that Chris Newton posted to comp.std.c++:</i> |
| </p> |
| |
| <p> |
| The standard's description of <tt>basic_string<>::operator[]</tt> |
| seems to violate const correctness. |
| </p> |
| |
| <p> |
| The standard (21.3.4/1) says that "If <tt>pos < size()</tt>, |
| returns <tt>data()[pos]</tt>." The types don't work. The |
| return value of <tt>data()</tt> is <tt>const charT*</tt>, but |
| <tt>operator[]</tt> has a non-const version whose return type is <tt>reference</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 21.3.4, paragraph 1, change |
| "<tt>data()[<i>pos</i>]</tt>" to "<tt>*(begin() + |
| <i>pos</i>)</tt>". |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="260"></a>260. Inconsistent return type of <tt>istream_iterator::operator++(int)</tt></h3> |
| <p><b>Section:</b> 24.5.1.2 [istream.iterator.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-08-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.iterator.ops">issues</a> in [istream.iterator.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The synopsis of istream_iterator::operator++(int) in 24.5.1 shows |
| it as returning the iterator by value. 24.5.1.2, p5 shows the same |
| operator as returning the iterator by reference. That's incorrect |
| given the Effects clause below (since a temporary is returned). The |
| `&' is probably just a typo.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the declaration in 24.5.1.2, p5 from</p> |
| <pre> istream_iterator<T,charT,traits,Distance>& operator++(int); |
| </pre> |
| <p>to</p> |
| <pre> istream_iterator<T,charT,traits,Distance> operator++(int); |
| </pre> |
| <p>(that is, remove the `&').</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="261"></a>261. Missing description of <tt>istream_iterator::operator!=</tt></h3> |
| <p><b>Section:</b> 24.5.1.2 [istream.iterator.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-08-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.iterator.ops">issues</a> in [istream.iterator.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 24.5.1, p3 lists the synopsis for |
| </p> |
| |
| <pre> template <class T, class charT, class traits, class Distance> |
| bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, |
| const istream_iterator<T,charT,traits,Distance>& y); |
| </pre> |
| |
| <p> |
| but there is no description of what the operator does (i.e., no Effects |
| or Returns clause) in 24.5.1.2. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add paragraph 7 to the end of section 24.5.1.2 with the following text: |
| </p> |
| |
| <pre> template <class T, class charT, class traits, class Distance> |
| bool operator!=(const istream_iterator<T,charT,traits,Distance>& x, |
| const istream_iterator<T,charT,traits,Distance>& y); |
| </pre> |
| |
| <p>-7- Returns: !(x == y).</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="262"></a>262. Bitmask operator ~ specified incorrectly</h3> |
| <p><b>Section:</b> 17.3.2.1.2 [bitmask.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2000-09-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The ~ operation should be applied after the cast to int_type. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 17.3.2.1.2 [lib.bitmask.types] operator~ from: |
| </p> |
| |
| <pre> bitmask operator~ ( bitmask X ) |
| { return static_cast< bitmask>(static_cast<int_type>(~ X)); } |
| </pre> |
| |
| <p> |
| to: |
| </p> |
| |
| <pre> bitmask operator~ ( bitmask X ) |
| { return static_cast< bitmask>(~static_cast<int_type>(X)); } |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="263"></a>263. Severe restriction on <tt>basic_string</tt> reference counting</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Kevlin Henney <b>Date:</b> 2000-09-04</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The note in paragraph 6 suggests that the invalidation rules for |
| references, pointers, and iterators in paragraph 5 permit a reference- |
| counted implementation (actually, according to paragraph 6, they permit |
| a "reference counted implementation", but this is a minor editorial fix). |
| </p> |
| |
| <p> |
| However, the last sub-bullet is so worded as to make a reference-counted |
| implementation unviable. In the following example none of the |
| conditions for iterator invalidation are satisfied: |
| </p> |
| |
| <pre> // first example: "*******************" should be printed twice |
| string original = "some arbitrary text", copy = original; |
| const string & alias = original; |
| |
| string::const_iterator i = alias.begin(), e = alias.end(); |
| for(string::iterator j = original.begin(); j != original.end(); ++j) |
| *j = '*'; |
| while(i != e) |
| cout << *i++; |
| cout << endl; |
| cout << original << endl; |
| </pre> |
| |
| <p> |
| Similarly, in the following example: |
| </p> |
| |
| <pre> // second example: "some arbitrary text" should be printed out |
| string original = "some arbitrary text", copy = original; |
| const string & alias = original; |
| |
| string::const_iterator i = alias.begin(); |
| original.begin(); |
| while(i != alias.end()) |
| cout << *i++; |
| </pre> |
| |
| <p> |
| I have tested this on three string implementations, two of which were |
| reference counted. The reference-counted implementations gave |
| "surprising behavior" because they invalidated iterators on |
| the first call to non-const begin since construction. The current |
| wording does not permit such invalidation because it does not take |
| into account the first call since construction, only the first call |
| since various member and non-member function calls. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the following sentence in 21.3 paragraph 5 from |
| </p> |
| |
| <blockquote><p> |
| Subsequent to any of the above uses except the forms of insert() and |
| erase() which return iterators, the first call to non-const member |
| functions operator[](), at(), begin(), rbegin(), end(), or rend(). |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| Following construction or any of the above uses, except the forms of |
| insert() and erase() that return iterators, the first call to non- |
| const member functions operator[](), at(), begin(), rbegin(), end(), |
| or rend(). |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="264"></a>264. Associative container <tt>insert(i, j)</tt> complexity requirements are not feasible.</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> John Potter <b>Date:</b> 2000-09-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#102">102</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 69 requires linear time if [i, j) is sorted. Sorted is necessary but not sufficient. |
| Consider inserting a sorted range of even integers into a set<int> containing the odd |
| integers in the same range. |
| </p> |
| |
| <p><i>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#102">102</a></i></p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In Table 69, in section 23.1.2, change the complexity clause for |
| insertion of a range from "N log(size() + N) (N is the distance |
| from i to j) in general; linear if [i, j) is sorted according to |
| value_comp()" to "N log(size() + N), where N is the distance |
| from i to j". |
| </p> |
| |
| <p><i>[Copenhagen: Minor fix in proposed resolution: fixed unbalanced |
| parens in the revised wording.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Testing for valid insertions could be less efficient than simply |
| inserting the elements when the range is not both sorted and between |
| two adjacent existing elements; this could be a QOI issue. |
| </p> |
| |
| <p> |
| The LWG considered two other options: (a) specifying that the |
| complexity was linear if [i, j) is sorted according to value_comp() |
| and between two adjacent existing elements; or (b) changing to |
| Klog(size() + N) + (N - K) (N is the distance from i to j and K is the |
| number of elements which do not insert immediately after the previous |
| element from [i, j) including the first). The LWG felt that, since |
| we can't guarantee linear time complexity whenever the range to be |
| inserted is sorted, it's more trouble than it's worth to say that it's |
| linear in some special cases. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="265"></a>265. std::pair::pair() effects overly restrictive</h3> |
| <p><b>Section:</b> 20.2.3 [pairs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-09-11</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#pairs">issues</a> in [pairs].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I don't see any requirements on the types of the elements of the |
| std::pair container in 20.2.2. From the descriptions of the member |
| functions it appears that they must at least satisfy the requirements of |
| 20.1.3 [lib.copyconstructible] and 20.1.4 [lib.default.con.req], and in |
| the case of the [in]equality operators also the requirements of 20.1.1 |
| [lib.equalitycomparable] and 20.1.2 [lib.lessthancomparable]. |
| </p> |
| |
| <p> |
| I believe that the the CopyConstructible requirement is unnecessary in |
| the case of 20.2.2, p2. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Effects clause in 20.2.2, p2 from</p> |
| |
| <blockquote><p> |
| -2- <b>Effects</b>: Initializes its members as if implemented: <tt> pair() : |
| first(T1()), second(T2()) {} </tt> |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| -2- <b>Effects</b>: Initializes its members as if implemented: <tt> pair() : |
| first(), second() {} </tt> |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The existing specification of pair's constructor appears to be a |
| historical artifact: there was concern that pair's members be properly |
| zero-initialized when they are built-in types. At one time there was |
| uncertainty about whether they would be zero-initialized if the |
| default constructor was written the obvious way. This has been |
| clarified by core issue 178, and there is no longer any doubt that |
| the straightforward implementation is correct.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="266"></a>266. bad_exception::~bad_exception() missing Effects clause</h3> |
| <p><b>Section:</b> 18.7.2.1 [bad.exception] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-09-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The synopsis for std::bad_exception lists the function ~bad_exception() |
| but there is no description of what the function does (the Effects |
| clause is missing). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove the destructor from the class synopses of |
| <tt>bad_alloc</tt> (18.5.2.1 [bad.alloc]), |
| <tt>bad_cast</tt> (18.6.2 [bad.cast]), |
| <tt>bad_typeid</tt> (18.6.3 [bad.typeid]), |
| and <tt>bad_exception</tt> (18.7.2.1 [bad.exception]). |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This is a general problem with the exception classes in clause 18. |
| The proposed resolution is to remove the destructors from the class |
| synopses, rather than to document the destructors' behavior, because |
| removing them is more consistent with how exception classes are |
| described in clause 19. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="268"></a>268. Typo in locale synopsis</h3> |
| <p><b>Section:</b> 22.1.1 [locale] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-10-05</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale">issues</a> in [locale].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The synopsis of the class std::locale in 22.1.1 contains two typos: |
| the semicolons after the declarations of the default ctor |
| locale::locale() and the copy ctor locale::locale(const locale&) |
| are missing.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the missing semicolons, i.e., change</p> |
| |
| <pre> // construct/copy/destroy: |
| locale() throw() |
| locale(const locale& other) throw() |
| </pre> |
| |
| <p>in the synopsis in 22.1.1 to</p> |
| |
| <pre> // construct/copy/destroy: |
| locale() throw(); |
| locale(const locale& other) throw(); |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="270"></a>270. Binary search requirements overly strict</h3> |
| <p><b>Section:</b> 25.3.3 [alg.binary.search] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2000-10-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.binary.search">issues</a> in [alg.binary.search].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#472">472</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Each of the four binary search algorithms (lower_bound, upper_bound, |
| equal_range, binary_search) has a form that allows the user to pass a |
| comparison function object. According to 25.3, paragraph 2, that |
| comparison function object has to be a strict weak ordering. |
| </p> |
| |
| <p> |
| This requirement is slightly too strict. Suppose we are searching |
| through a sequence containing objects of type X, where X is some |
| large record with an integer key. We might reasonably want to look |
| up a record by key, in which case we would want to write something |
| like this: |
| </p> |
| <pre> struct key_comp { |
| bool operator()(const X& x, int n) const { |
| return x.key() < n; |
| } |
| } |
| |
| std::lower_bound(first, last, 47, key_comp()); |
| </pre> |
| |
| <p> |
| key_comp is not a strict weak ordering, but there is no reason to |
| prohibit its use in lower_bound. |
| </p> |
| |
| <p> |
| There's no difficulty in implementing lower_bound so that it allows |
| the use of something like key_comp. (It will probably work unless an |
| implementor takes special pains to forbid it.) What's difficult is |
| formulating language in the standard to specify what kind of |
| comparison function is acceptable. We need a notion that's slightly |
| more general than that of a strict weak ordering, one that can encompass |
| a comparison function that involves different types. Expressing that |
| notion may be complicated. |
| </p> |
| |
| <p><i>Additional questions raised at the Toronto meeting:</i></p> |
| <ul> |
| <li> Do we really want to specify what ordering the implementor must |
| use when calling the function object? The standard gives |
| specific expressions when describing these algorithms, but it also |
| says that other expressions (with different argument order) are |
| equivalent.</li> |
| <li> If we are specifying ordering, note that the standard uses both |
| orderings when describing <tt>equal_range</tt>.</li> |
| <li> Are we talking about requiring these algorithms to work properly |
| when passed a binary function object whose two argument types |
| are not the same, or are we talking about requirements when |
| they are passed a binary function object with several overloaded |
| versions of <tt>operator()</tt>?</li> |
| <li> The definition of a strict weak ordering does not appear to give |
| any guidance on issues of overloading; it only discusses expressions, |
| and all of the values in these expressions are of the same type. |
| Some clarification would seem to be in order.</li> |
| </ul> |
| |
| <p><i>Additional discussion from Copenhagen:</i></p> |
| <ul> |
| <li>It was generally agreed that there is a real defect here: if |
| the predicate is merely required to be a Strict Weak Ordering, then |
| it's possible to pass in a function object with an overloaded |
| operator(), where the version that's actually called does something |
| completely inappropriate. (Such as returning a random value.)</li> |
| |
| <li>An alternative formulation was presented in a paper distributed by |
| David Abrahams at the meeting, "Binary Search with Heterogeneous |
| Comparison", J16-01/0027 = WG21 N1313: Instead of viewing the |
| predicate as a Strict Weak Ordering acting on a sorted sequence, view |
| the predicate/value pair as something that partitions a sequence. |
| This is almost equivalent to saying that we should view binary search |
| as if we are given a unary predicate and a sequence, such that f(*p) |
| is true for all p below a specific point and false for all p above it. |
| The proposed resolution is based on that alternative formulation.</li> |
| </ul> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change 25.3 [lib.alg.sorting] paragraph 3 from:</p> |
| |
| <blockquote><p> |
| 3 For all algorithms that take Compare, there is a version that uses |
| operator< instead. That is, comp(*i, *j) != false defaults to *i < |
| *j != false. For the algorithms to work correctly, comp has to |
| induce a strict weak ordering on the values. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| 3 For all algorithms that take Compare, there is a version that uses |
| operator< instead. That is, comp(*i, *j) != false defaults to *i |
| < *j != false. For algorithms other than those described in |
| lib.alg.binary.search (25.3.3) to work correctly, comp has to induce |
| a strict weak ordering on the values. |
| </p></blockquote> |
| |
| <p>Add the following paragraph after 25.3 [lib.alg.sorting] paragraph 5:</p> |
| |
| <blockquote><p> |
| -6- A sequence [start, finish) is partitioned with respect to an |
| expression f(e) if there exists an integer n such that |
| for all 0 <= i < distance(start, finish), f(*(begin+i)) is true if |
| and only if i < n. |
| </p></blockquote> |
| |
| <p>Change 25.3.3 [lib.alg.binary.search] paragraph 1 from:</p> |
| |
| <blockquote><p> |
| -1- All of the algorithms in this section are versions of binary |
| search and assume that the sequence being searched is in order |
| according to the implied or explicit comparison function. They work |
| on non-random access iterators minimizing the number of |
| comparisons, which will be logarithmic for all types of |
| iterators. They are especially appropriate for random access |
| iterators, because these algorithms do a logarithmic number of |
| steps through the data structure. For non-random access iterators |
| they execute a linear number of steps. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -1- All of the algorithms in this section are versions of binary |
| search and assume that the sequence being searched is partitioned |
| with respect to an expression formed by binding the search key to |
| an argument of the implied or explicit comparison function. They |
| work on non-random access iterators minimizing the number of |
| comparisons, which will be logarithmic for all types of |
| iterators. They are especially appropriate for random access |
| iterators, because these algorithms do a logarithmic number of |
| steps through the data structure. For non-random access iterators |
| they execute a linear number of steps. |
| </p></blockquote> |
| |
| <p>Change 25.3.3.1 [lib.lower.bound] paragraph 1 from:</p> |
| |
| <blockquote><p> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expression e < value or comp(e, value) |
| </p></blockquote> |
| |
| |
| <p>Remove 25.3.3.1 [lib.lower.bound] paragraph 2:</p> |
| |
| <blockquote><p> |
| -2- Effects: Finds the first position into which value can be |
| inserted without violating the ordering. |
| </p></blockquote> |
| |
| <p>Change 25.3.3.2 [lib.upper.bound] paragraph 1 from:</p> |
| |
| <blockquote><p> |
| -1- Requires: Type T is LessThanComparable (lib.lessthancomparable). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expression !(value < e) or !comp(value, e) |
| </p></blockquote> |
| |
| <p>Remove 25.3.3.2 [lib.upper.bound] paragraph 2:</p> |
| |
| <blockquote><p> |
| -2- Effects: Finds the furthermost position into which value can be |
| inserted without violating the ordering. |
| </p></blockquote> |
| |
| <p>Change 25.3.3.3 [lib.equal.range] paragraph 1 from:</p> |
| |
| <blockquote><p> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expressions e < value and !(value < e) or |
| comp(e, value) and !comp(value, e). Also, for all elements e of |
| [first, last), e < value implies !(value < e) or comp(e, |
| value) implies !comp(value, e) |
| </p></blockquote> |
| |
| <p>Change 25.3.3.3 [lib.equal.range] paragraph 2 from:</p> |
| |
| <blockquote><p> |
| -2- Effects: Finds the largest subrange [i, j) such that the value |
| can be inserted at any iterator k in it without violating the |
| ordering. k satisfies the corresponding conditions: !(*k < value) |
| && !(value < *k) or comp(*k, value) == false && comp(value, *k) == |
| false. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <pre> -2- Returns: |
| make_pair(lower_bound(first, last, value), |
| upper_bound(first, last, value)) |
| or |
| make_pair(lower_bound(first, last, value, comp), |
| upper_bound(first, last, value, comp)) |
| </pre> |
| |
| <p>Change 25.3.3.3 [lib.binary.search] paragraph 1 from:</p> |
| |
| <blockquote><p> |
| -1- Requires: Type T is LessThanComparable |
| (lib.lessthancomparable). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -1- Requires: The elements e of [first, last) are partitioned with |
| respect to the expressions e < value and !(value < e) or comp(e, |
| value) and !comp(value, e). Also, for all elements e of [first, |
| last), e < value implies !(value < e) or comp(e, value) implies |
| !comp(value, e) |
| </p></blockquote> |
| |
| <p><i>[Copenhagen: Dave Abrahams provided this wording]</i></p> |
| |
| |
| <p><i>[Redmond: Minor changes in wording. (Removed "non-negative", and |
| changed the "other than those described in" wording.) Also, the LWG |
| decided to accept the "optional" part.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution reinterprets binary search. Instead of |
| thinking about searching for a value in a sorted range, we view that |
| as an important special case of a more general algorithm: searching |
| for the partition point in a partitioned range.</p> |
| |
| <p>We also add a guarantee that the old wording did not: we ensure |
| that the upper bound is no earlier than the lower bound, that |
| the pair returned by equal_range is a valid range, and that the first |
| part of that pair is the lower bound.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="271"></a>271. basic_iostream missing typedefs</h3> |
| <p><b>Section:</b> 27.6.1.5 [iostreamclass] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-11-02</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Class template basic_iostream has no typedefs. The typedefs it |
| inherits from its base classes can't be used, since (for example) |
| basic_iostream<T>::traits_type is ambiguous. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to basic_iostream's class synopsis in |
| 27.6.1.5 [iostreamclass], immediately after <tt>public</tt>:</p> |
| |
| <pre> // types: |
| typedef charT char_type; |
| typedef typename traits::int_type int_type; |
| typedef typename traits::pos_type pos_type; |
| typedef typename traits::off_type off_type; |
| typedef traits traits_type; |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="272"></a>272. Missing parentheses around subexpression</h3> |
| <p><b>Section:</b> 27.4.4.3 [iostate.flags] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-11-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostate.flags">issues</a> in [iostate.flags].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#569">569</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 27.4.4.3, p4 says about the postcondition of the function: If |
| rdbuf()!=0 then state == rdstate(); otherwise |
| rdstate()==state|ios_base::badbit. |
| </p> |
| |
| <p> |
| The expression on the right-hand-side of the operator==() needs to be |
| parenthesized in order for the whole expression to ever evaluate to |
| anything but non-zero. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add parentheses like so: rdstate()==(state|ios_base::badbit). |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="273"></a>273. Missing ios_base qualification on members of a dependent class</h3> |
| <p><b>Section:</b> 27 [input.output] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-11-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.output">issues</a> in [input.output].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.5.2.4.2, p4, and 27.8.1.6, p2, 27.8.1.7, p3, 27.8.1.9, p2, |
| 27.8.1.10, p3 refer to in and/or out w/o ios_base:: qualification. |
| That's incorrect since the names are members of a dependent base |
| class (14.6.2 [temp.dep]) and thus not visible.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Qualify the names with the name of the class of which they are |
| members, i.e., ios_base.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="274"></a>274. a missing/impossible allocator requirement</h3> |
| <p><b>Section:</b> 20.1.2 [allocator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-11-02</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I see that table 31 in 20.1.5, p3 allows T in std::allocator<T> to be of |
| any type. But the synopsis in 20.4.1 calls for allocator<>::address() to |
| be overloaded on reference and const_reference, which is ill-formed for |
| all T = const U. In other words, this won't work: |
| </p> |
| |
| <p> |
| template class std::allocator<const int>; |
| </p> |
| |
| <p> |
| The obvious solution is to disallow specializations of allocators on |
| const types. However, while containers' elements are required to be |
| assignable (which rules out specializations on const T's), I think that |
| allocators might perhaps be potentially useful for const values in other |
| contexts. So if allocators are to allow const types a partial |
| specialization of std::allocator<const T> would probably have to be |
| provided. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in row 1, column 2 of table 32 in 20.1.5, p3 from</p> |
| |
| <blockquote><p> |
| any type |
| </p></blockquote> |
| |
| <p>to</p> |
| <blockquote><p> |
| any non-const, non-reference type |
| </p></blockquote> |
| |
| <p><i>[Redmond: previous proposed resolution was "any non-const, |
| non-volatile, non-reference type". Got rid of the "non-volatile".]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Two resolutions were originally proposed: one that partially |
| specialized std::allocator for const types, and one that said an |
| allocator's value type may not be const. The LWG chose the second. |
| The first wouldn't be appropriate, because allocators are intended for |
| use by containers, and const value types don't work in containers. |
| Encouraging the use of allocators with const value types would only |
| lead to unsafe code. |
| </p> |
| <p> |
| The original text for proposed resolution 2 was modified so that it |
| also forbids volatile types and reference types. |
| </p> |
| |
| <p><i>[Curaçao: LWG double checked and believes volatile is correctly |
| excluded from the PR.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="275"></a>275. Wrong type in num_get::get() overloads</h3> |
| <p><b>Section:</b> 22.2.2.1.1 [facet.num.get.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2000-11-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.members">issues</a> in [facet.num.get.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 22.2.2.1.1, we have a list of overloads for num_get<>::get(). |
| There are eight overloads, all of which are identical except for the |
| last parameter. The overloads are: |
| </p> |
| <ul> |
| <li> long& </li> |
| <li> unsigned short& </li> |
| <li> unsigned int& </li> |
| <li> unsigned long& </li> |
| <li> short& </li> |
| <li> double& </li> |
| <li> long double& </li> |
| <li> void*& </li> |
| </ul> |
| |
| <p> |
| There is a similar list, in 22.2.2.1.2, of overloads for |
| num_get<>::do_get(). In this list, the last parameter has |
| the types: |
| </p> |
| <ul> |
| <li> long& </li> |
| <li> unsigned short& </li> |
| <li> unsigned int& </li> |
| <li> unsigned long& </li> |
| <li> float& </li> |
| <li> double& </li> |
| <li> long double& </li> |
| <li> void*& </li> |
| </ul> |
| |
| <p> |
| These two lists are not identical. They should be, since |
| <tt>get</tt> is supposed to call <tt>do_get</tt> with exactly |
| the arguments it was given. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.1.1 [facet.num.get.members], change</p> |
| <pre> iter_type get(iter_type in, iter_type end, ios_base& str, |
| ios_base::iostate& err, short& val) const; |
| </pre> |
| <p>to</p> |
| <pre> iter_type get(iter_type in, iter_type end, ios_base& str, |
| ios_base::iostate& err, float& val) const; |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="276"></a>276. Assignable requirement for container value type overly strict</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2000-11-07</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 23.1/3 states that the objects stored in a container must be |
| Assignable. 23.3.1 [map], paragraph 2, |
| states that map satisfies all requirements for a container, while in |
| the same time defining value_type as pair<const Key, T> - a type |
| that is not Assignable. |
| </p> |
| |
| <p> |
| It should be noted that there exists a valid and non-contradictory |
| interpretation of the current text. The wording in 23.1/3 avoids |
| mentioning value_type, referring instead to "objects stored in a |
| container." One might argue that map does not store objects of |
| type map::value_type, but of map::mapped_type instead, and that the |
| Assignable requirement applies to map::mapped_type, not |
| map::value_type. |
| </p> |
| |
| <p> |
| However, this makes map a special case (other containers store objects of |
| type value_type) and the Assignable requirement is needlessly restrictive in |
| general. |
| </p> |
| |
| <p> |
| For example, the proposed resolution of active library issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#103">103</a> is to make set::iterator a constant iterator; this |
| means that no set operations can exploit the fact that the stored |
| objects are Assignable. |
| </p> |
| |
| <p> |
| This is related to, but slightly broader than, closed issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#140">140</a>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>23.1/3: Strike the trailing part of the sentence:</p> |
| <blockquote><p> |
| , and the additional requirements of Assignable types from 23.1/3 |
| </p></blockquote> |
| <p>so that it reads:</p> |
| <blockquote><p> |
| -3- The type of objects stored in these components must meet the |
| requirements of CopyConstructible types (lib.copyconstructible). |
| </p></blockquote> |
| |
| <p>23.1/4: Modify to make clear that this requirement is not for all |
| containers. Change to:</p> |
| |
| <blockquote><p> |
| -4- Table 64 defines the Assignable requirement. Some containers |
| require this property of the types to be stored in the container. T is |
| the type used to instantiate the container. t is a value of T, and u is |
| a value of (possibly const) T. |
| </p></blockquote> |
| |
| <p>23.1, Table 65: in the first row, change "T is Assignable" to "T is |
| CopyConstructible".</p> |
| |
| <p>23.2.1/2: Add sentence for Assignable requirement. Change to:</p> |
| |
| <blockquote><p> |
| -2- A deque satisfies all of the requirements of a container and of a |
| reversible container (given in tables in lib.container.requirements) and |
| of a sequence, including the optional sequence requirements |
| (lib.sequence.reqmts). In addition to the requirements on the stored |
| object described in 23.1[lib.container.requirements], the stored object |
| must also meet the requirements of Assignable. Descriptions are |
| provided here only for operations on deque that are not described in one |
| of these tables or for operations where there is additional semantic |
| information. |
| </p></blockquote> |
| |
| <p>23.2.2/2: Add Assignable requirement to specific methods of list. |
| Change to:</p> |
| |
| <blockquote> |
| <p>-2- A list satisfies all of the requirements of a container and of a |
| reversible container (given in two tables in lib.container.requirements) |
| and of a sequence, including most of the the optional sequence |
| requirements (lib.sequence.reqmts). The exceptions are the operator[] |
| and at member functions, which are not provided. |
| |
| [Footnote: These member functions are only provided by containers whose |
| iterators are random access iterators. --- end foonote] |
| </p> |
| |
| <p>list does not require the stored type T to be Assignable unless the |
| following methods are instantiated: |
| |
| [Footnote: Implementors are permitted but not required to take advantage |
| of T's Assignable properties for these methods. -- end foonote] |
| </p> |
| <pre> list<T,Allocator>& operator=(const list<T,Allocator>& x ); |
| template <class InputIterator> |
| void assign(InputIterator first, InputIterator last); |
| void assign(size_type n, const T& t); |
| </pre> |
| |
| |
| <p>Descriptions are provided here only for operations on list that are not |
| described in one of these tables or for operations where there is |
| additional semantic information.</p> |
| </blockquote> |
| |
| <p>23.2.4/2: Add sentence for Assignable requirement. Change to:</p> |
| |
| <blockquote><p> |
| -2- A vector satisfies all of the requirements of a container and of a |
| reversible container (given in two tables in lib.container.requirements) |
| and of a sequence, including most of the optional sequence requirements |
| (lib.sequence.reqmts). The exceptions are the push_front and pop_front |
| member functions, which are not provided. In addition to the |
| requirements on the stored object described in |
| 23.1[lib.container.requirements], the stored object must also meet the |
| requirements of Assignable. Descriptions are provided here only for |
| operations on vector that are not described in one of these tables or |
| for operations where there is additional semantic information. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>list, set, multiset, map, multimap are able to store non-Assignables. |
| However, there is some concern about <tt>list<T></tt>: |
| although in general there's no reason for T to be Assignable, some |
| implementations of the member functions <tt>operator=</tt> and |
| <tt>assign</tt> do rely on that requirement. The LWG does not want |
| to forbid such implementations.</p> |
| |
| <p>Note that the type stored in a standard container must still satisfy |
| the requirements of the container's allocator; this rules out, for |
| example, such types as "const int". See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#274">274</a> |
| for more details. |
| </p> |
| |
| <p>In principle we could also relax the "Assignable" requirement for |
| individual <tt>vector</tt> member functions, such as |
| <tt>push_back</tt>. However, the LWG did not see great value in such |
| selective relaxation. Doing so would remove implementors' freedom to |
| implement <tt>vector::push_back</tt> in terms of |
| <tt>vector::insert</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="278"></a>278. What does iterator validity mean?</h3> |
| <p><b>Section:</b> 23.2.4.4 [list.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger <b>Date:</b> 2000-11-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.ops">issues</a> in [list.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 23.2.4.4 [list.ops] states that |
| </p> |
| <pre> void splice(iterator position, list<T, Allocator>& x); |
| </pre> |
| <p> |
| <i>invalidates</i> all iterators and references to list <tt>x</tt>. |
| </p> |
| |
| <p> |
| But what does the C++ Standard mean by "invalidate"? You |
| can still dereference the iterator to a spliced list element, but |
| you'd better not use it to delimit a range within the original |
| list. For the latter operation, it has definitely lost some of its |
| validity. |
| </p> |
| |
| <p> |
| If we accept the proposed resolution to issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#250">250</a>, |
| then we'd better clarify that a "valid" iterator need no |
| longer designate an element within the same container as it once did. |
| We then have to clarify what we mean by invalidating a past-the-end |
| iterator, as when a vector or string grows by reallocation. Clearly, |
| such an iterator has a different kind of validity. Perhaps we should |
| introduce separate terms for the two kinds of "validity." |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of section 24.1 [iterator.requirements], |
| after paragraph 5:</p> |
| <blockquote><p> |
| An <i>invalid</i> iterator is an iterator that may be |
| singular. [Footnote: This definition applies to pointers, since |
| pointers are iterators. The effect of dereferencing an iterator that |
| has been invalidated is undefined.] |
| </p></blockquote> |
| |
| <p><i>[post-Copenhagen: Matt provided wording.]</i></p> |
| |
| |
| <p><i>[Redmond: General agreement with the intent, some objections to |
| the wording. Dave provided new wording.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This resolution simply defines a term that the Standard uses but |
| never defines, "invalid", in terms of a term that is defined, |
| "singular".</p> |
| |
| <p>Why do we say "may be singular", instead of "is singular"? That's |
| becuase a valid iterator is one that is known to be nonsingular. |
| Invalidating an iterator means changing it in such a way that it's |
| no longer known to be nonsingular. An example: inserting an |
| element into the middle of a vector is correctly said to invalidate |
| all iterators pointing into the vector. That doesn't necessarily |
| mean they all become singular.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="280"></a>280. Comparison of reverse_iterator to const reverse_iterator</h3> |
| <p><b>Section:</b> 24.4.1 [reverse.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve Cleary <b>Date:</b> 2000-11-27</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| This came from an email from Steve Cleary to Fergus in reference to |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#179">179</a>. The library working group briefly discussed |
| this in Toronto and believed it should be a separate issue. There was |
| also some reservations about whether this was a worthwhile problem to |
| fix. |
| </p> |
| |
| <p> |
| Steve said: "Fixing reverse_iterator. std::reverse_iterator can |
| (and should) be changed to preserve these additional |
| requirements." He also said in email that it can be done without |
| breaking user's code: "If you take a look at my suggested |
| solution, reverse_iterator doesn't have to take two parameters; there |
| is no danger of breaking existing code, except someone taking the |
| address of one of the reverse_iterator global operator functions, and |
| I have to doubt if anyone has ever done that. . . <i>But</i>, just in |
| case they have, you can leave the old global functions in as well -- |
| they won't interfere with the two-template-argument functions. With |
| that, I don't see how <i>any</i> user code could break." |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| <b>Section:</b> 24.4.1.1 [reverse.iterator] |
| add/change the following declarations:</p> |
| <pre> A) Add a templated assignment operator, after the same manner |
| as the templated copy constructor, i.e.: |
| |
| template < class U > |
| reverse_iterator < Iterator >& operator=(const reverse_iterator< U >& u); |
| |
| B) Make all global functions (except the operator+) have |
| two template parameters instead of one, that is, for |
| operator ==, !=, <, >, <=, >=, - replace: |
| |
| template < class Iterator > |
| typename reverse_iterator< Iterator >::difference_type operator-( |
| const reverse_iterator< Iterator >& x, |
| const reverse_iterator< Iterator >& y); |
| |
| with: |
| |
| template < class Iterator1, class Iterator2 > |
| typename reverse_iterator < Iterator1 >::difference_type operator-( |
| const reverse_iterator < Iterator1 > & x, |
| const reverse_iterator < Iterator2 > & y); |
| </pre> |
| <p> |
| Also make the addition/changes for these signatures in |
| 24.4.1.3 [reverse.iter.ops]. |
| </p> |
| |
| <p><i>[ |
| Copenhagen: The LWG is concerned that the proposed resolution |
| introduces new overloads. Experience shows that introducing |
| overloads is always risky, and that it would be inappropriate to |
| make this change without implementation experience. It may be |
| desirable to provide this feature in a different way. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Lillehammer: We now have implementation experience, and agree that |
| this solution is safe and correct. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="281"></a>281. std::min() and max() requirements overly restrictive</h3> |
| <p><b>Section:</b> 25.3.7 [alg.min.max] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-12-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.min.max">issues</a> in [alg.min.max].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#486">486</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The requirements in 25.3.7, p1 and 4 call for T to satisfy the |
| requirements of <tt>LessThanComparable</tt> ( [lessthancomparable]) |
| and <tt>CopyConstructible</tt> (20.1.1 [utility.arg.requirements]). |
| Since the functions take and return their arguments and result by |
| const reference, I believe the <tt>CopyConstructible</tt> requirement |
| is unnecessary. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the <tt>CopyConstructible</tt> requirement. Specifically, replace |
| 25.3.7, p1 with</p> |
| <p><b>-1- Requires:</b> Type T is <tt>LessThanComparable</tt> |
| ( [lessthancomparable]). |
| </p> |
| <p>and replace 25.3.7, p4 with</p> |
| <p><b>-4- Requires:</b> Type T is <tt>LessThanComparable</tt> |
| ( [lessthancomparable]). |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="282"></a>282. What types does numpunct grouping refer to?</h3> |
| <p><b>Section:</b> 22.2.2.2.2 [facet.num.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2000-12-05</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.put.virtuals">issues</a> in [facet.num.put.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Paragraph 16 mistakenly singles out integral types for inserting |
| thousands_sep() characters. This conflicts with the syntax for floating |
| point numbers described under 22.2.3.1/2. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change paragraph 16 from:</p> |
| |
| <blockquote><p> |
| For integral types, punct.thousands_sep() characters are inserted into |
| the sequence as determined by the value returned by punct.do_grouping() |
| using the method described in 22.2.3.1.2 [facet.numpunct.virtuals]. |
| </p></blockquote> |
| |
| <p>To:</p> |
| |
| <blockquote><p> |
| For arithmetic types, punct.thousands_sep() characters are inserted into |
| the sequence as determined by the value returned by punct.do_grouping() |
| using the method described in 22.2.3.1.2 [facet.numpunct.virtuals]. |
| </p></blockquote> |
| |
| <p><i>[ |
| Copenhagen: Opinions were divided about whether this is actually an |
| inconsistency, but at best it seems to have been unintentional. This |
| is only an issue for floating-point output: The standard is |
| unambiguous that implementations must parse thousands_sep characters |
| when performing floating-point. The standard is also unambiguous that |
| this requirement does not apply to the "C" locale. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| A survey of existing practice is needed; it is believed that some |
| implementations do insert thousands_sep characters for floating-point |
| output and others fail to insert thousands_sep characters for |
| floating-point input even though this is unambiguously required by the |
| standard. |
| ]</i></p> |
| |
| |
| <p><i>[Post-Curaçao: the above proposed resolution is the consensus of |
| Howard, Bill, Pete, Benjamin, Nathan, Dietmar, Boris, and Martin.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="283"></a>283. std::replace() requirement incorrect/insufficient</h3> |
| <p><b>Section:</b> 25.2.5 [alg.replace] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-12-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.replace">issues</a> in [alg.replace].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#483">483</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| (revision of the further discussion) |
| There are a number of problems with the requires clauses for the |
| algorithms in 25.1 and 25.2. The requires clause of each algorithm |
| should describe the necessary and sufficient requirements on the inputs |
| to the algorithm such that the algorithm compiles and runs properly. |
| Many of the requires clauses fail to do this. Here is a summary of the kinds |
| of mistakes: |
| </p> |
| |
| <ol> |
| <li> |
| Use of EqualityComparable, which only puts requirements on a single |
| type, when in fact an equality operator is required between two |
| different types, typically either T and the iterator's value type |
| or between the value types of two different iterators. |
| </li> |
| <li> |
| Use of Assignable for T when in fact what was needed is Assignable |
| for the value_type of the iterator, and convertability from T to the |
| value_type of the iterator. Or for output iterators, the requirement |
| should be that T is writable to the iterator (output iterators do |
| not have value types). |
| </li> |
| </ol> |
| |
| <p> |
| Here is the list of algorithms that contain mistakes: |
| </p> |
| |
| <ul> |
| <li>25.1.2 std::find</li> |
| <li>25.1.6 std::count</li> |
| <li>25.1.8 std::equal</li> |
| <li>25.1.9 std::search, std::search_n</li> |
| <li>25.2.4 std::replace, std::replace_copy</li> |
| <li>25.2.5 std::fill</li> |
| <li>25.2.7 std::remove, std::remove_copy</li> |
| </ul> |
| |
| <p> |
| Also, in the requirements for EqualityComparable, the requirement that |
| the operator be defined for const objects is lacking. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>20.1.1 Change p1 from</p> |
| |
| <p>In Table 28, <tt>T</tt> is a type to be supplied by a C++ program |
| instantiating a template, <tt>a</tt>, <tt>b</tt>, and <tt>c</tt> are |
| values of type <tt>T</tt>. |
| </p> |
| |
| <p>to</p> |
| |
| <p> |
| In Table 28, <tt>T</tt> is a type to be supplied by a C++ program |
| instantiating a template, <tt>a</tt>, <tt>b</tt>, and <tt>c</tt> are |
| values of type <tt>const T</tt>. |
| </p> |
| |
| <p>25 Between p8 and p9</p> |
| |
| <p>Add the following sentence:</p> |
| |
| <p>When the description of an algorithm gives an expression such as |
| <tt>*first == value</tt> for a condition, it is required that the expression |
| evaluate to either true or false in boolean contexts.</p> |
| |
| <p>25.1.2 Change p1 by deleting the requires clause.</p> |
| |
| <p>25.1.6 Change p1 by deleting the requires clause.</p> |
| |
| <p>25.1.9</p> |
| |
| <p>Change p4 from</p> |
| |
| <p>-4- Requires: Type <tt>T</tt> is <tt>EqualityComparable</tt> |
| (20.1.1), type Size is convertible to integral type (4.7.12.3). |
| </p> |
| |
| <p>to</p> |
| |
| <p>-4- Requires: The type <tt>Size</tt> is convertible to integral |
| type (4.7.12.3).</p> |
| |
| <p>25.2.4 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1 ) (and, for <tt>replace()</tt>, <tt>EqualityComparable</tt> (20.1.1 )).</p> |
| |
| <p>to</p> |
| |
| <p>-1- Requires: The expression <tt>*first = new_value</tt> must be valid.</p> |
| |
| <p>and change p4 from</p> |
| |
| <p>-4- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1) (and, |
| for <tt>replace_copy()</tt>, <tt>EqualityComparable</tt> |
| (20.1.1)). The ranges <tt>[first, last)</tt> and <tt>[result, result + |
| (last - first))</tt> shall not overlap.</p> |
| |
| <p>to</p> |
| |
| <p>-4- Requires: The results of the expressions <tt>*first</tt> and |
| <tt>new_value</tt> must be writable to the result output iterator. The |
| ranges <tt>[first, last)</tt> and <tt>[result, result + (last - |
| first))</tt> shall not overlap.</p> |
| |
| |
| <p>25.2.5 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>Assignable</tt> (23.1). The |
| type <tt>Size</tt> is convertible to an integral type (4.7.12.3).</p> |
| |
| <p>to</p> |
| |
| <p>-1- Requires: The expression <tt>value</tt> must be is writable to |
| the output iterator. The type <tt>Size</tt> is convertible to an |
| integral type (4.7.12.3).</p> |
| |
| <p>25.2.7 Change p1 from</p> |
| |
| <p>-1- Requires: Type <tt>T</tt> is <tt>EqualityComparable</tt> (20.1.1).</p> |
| |
| <p>to</p> |
| |
| <p> |
| -1- Requires: The value type of the iterator must be |
| <tt>Assignable</tt> (23.1). |
| </p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The general idea of the proposed solution is to remove the faulty |
| requires clauses and let the returns and effects clauses speak for |
| themselves. That is, the returns clauses contain expressions that must |
| be valid, and therefore already imply the correct requirements. In |
| addition, a sentence is added at the beginning of chapter 25 saying |
| that expressions given as conditions must evaluate to true or false in |
| a boolean context. An alternative would be to say that the type of |
| these condition expressions must be literally bool, but that would be |
| imposing a greater restriction that what the standard currently says |
| (which is convertible to bool). |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="284"></a>284. unportable example in 20.3.7, p6</h3> |
| <p><b>Section:</b> 20.6.7 [comparisons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-12-26</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The example in 20.6.7 [comparisons], p6 shows how to use the C |
| library function <tt>strcmp()</tt> with the function pointer adapter |
| <tt>ptr_fun()</tt>. But since it's unspecified whether the C library |
| functions have <tt>extern "C"</tt> or <tt>extern |
| "C++"</tt> linkage [17.4.2.2 [using.linkage]], and since |
| function pointers with different the language linkage specifications |
| (7.5 [dcl.link]) are incompatible, whether this example is |
| well-formed is unspecified. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 20.6.7 [comparisons] paragraph 6 from:</p> |
| <blockquote> |
| <p>[<i>Example:</i></p> |
| <pre> replace_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(strcmp), "C")), "C++"); |
| </pre> |
| <p>replaces each <tt>C</tt> with <tt>C++</tt> in sequence <tt>v</tt>.</p> |
| </blockquote> |
| |
| |
| <p>to:</p> |
| <blockquote> |
| <p>[<i>Example:</i></p> |
| <pre> int compare(const char*, const char*); |
| replace_if(v.begin(), v.end(), |
| not1(bind2nd(ptr_fun(compare), "abc")), "def"); |
| </pre> |
| <p>replaces each <tt>abc</tt> with <tt>def</tt> in sequence <tt>v</tt>.</p> |
| </blockquote> |
| |
| <p>Also, remove footnote 215 in that same paragraph.</p> |
| |
| <p><i>[Copenhagen: Minor change in the proposed resolution. Since this |
| issue deals in part with C and C++ linkage, it was believed to be too |
| confusing for the strings in the example to be "C" and "C++". |
| ]</i></p> |
| |
| |
| <p><i>[Redmond: More minor changes. Got rid of the footnote (which |
| seems to make a sweeping normative requirement, even though footnotes |
| aren't normative), and changed the sentence after the footnote so that |
| it corresponds to the new code fragment.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="285"></a>285. minor editorial errors in fstream ctors</h3> |
| <p><b>Section:</b> 27.8.1.7 [ifstream.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2000-12-31</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.8.1.7 [ifstream.cons], p2, 27.8.1.11 [ofstream.cons], p2, and |
| 27.8.1.15 [fstream.cons], p2 say about the effects of each constructor: |
| </p> |
| |
| <p>... If that function returns a null pointer, calls |
| <tt>setstate(failbit)</tt> (which may throw <tt>ios_base::failure</tt>). |
| </p> |
| |
| <p>The parenthetical note doesn't apply since the ctors cannot throw an |
| exception due to the requirement in 27.4.4.1 [basic.ios.cons], p3 |
| that <tt>exceptions()</tt> be initialized to <tt>ios_base::goodbit</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Strike the parenthetical note from the Effects clause in each of the |
| paragraphs mentioned above. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="286"></a>286. <cstdlib> requirements missing size_t typedef</h3> |
| <p><b>Section:</b> 25.4 [alg.c.library] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 2000-12-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.c.library">issues</a> in [alg.c.library].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The <cstdlib> header file contains prototypes for bsearch and |
| qsort (C++ Standard section 25.4 paragraphs 3 and 4) and other |
| prototypes (C++ Standard section 21.4 paragraph 1 table 49) that |
| require the typedef size_t. Yet size_t is not listed in the |
| <cstdlib> synopsis table 78 in section 25.4. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the type size_t to Table 78 (section 25.4) and add |
| the type size_t <cstdlib> to Table 97 (section C.2). |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Since size_t is in <stdlib.h>, it must also be in <cstdlib>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="288"></a>288. <cerrno> requirements missing macro EILSEQ</h3> |
| <p><b>Section:</b> 19.3 [errno] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Judy Ward <b>Date:</b> 2000-12-30</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| ISO/IEC 9899:1990/Amendment1:1994 Section 4.3 States: "The list |
| of macros defined in <errno.h> is adjusted to include a new |
| macro, EILSEQ" |
| </p> |
| |
| <p> |
| ISO/IEC 14882:1998(E) section 19.3 does not refer |
| to the above amendment. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Update Table 26 (section 19.3) "Header <cerrno> synopsis" |
| and Table 95 (section C.2) "Standard Macros" to include EILSEQ. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="291"></a>291. Underspecification of set algorithms</h3> |
| <p><b>Section:</b> 25.3.5 [alg.set.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2001-01-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.set.operations">issues</a> in [alg.set.operations].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The standard library contains four algorithms that compute set |
| operations on sorted ranges: <tt>set_union</tt>, <tt>set_intersection</tt>, |
| <tt>set_difference</tt>, and <tt>set_symmetric_difference</tt>. Each |
| of these algorithms takes two sorted ranges as inputs, and writes the |
| output of the appropriate set operation to an output range. The elements |
| in the output range are sorted. |
| </p> |
| |
| <p> |
| The ordinary mathematical definitions are generalized so that they |
| apply to ranges containing multiple copies of a given element. Two |
| elements are considered to be "the same" if, according to an |
| ordering relation provided by the user, neither one is less than the |
| other. So, for example, if one input range contains five copies of an |
| element and another contains three, the output range of <tt>set_union</tt> |
| will contain five copies, the output range of |
| <tt>set_intersection</tt> will contain three, the output range of |
| <tt>set_difference</tt> will contain two, and the output range of |
| <tt>set_symmetric_difference</tt> will contain two. |
| </p> |
| |
| <p> |
| Because two elements can be "the same" for the purposes |
| of these set algorithms, without being identical in other respects |
| (consider, for example, strings under case-insensitive comparison), |
| this raises a number of unanswered questions: |
| </p> |
| |
| <ul> |
| <li>If we're copying an element that's present in both of the |
| input ranges, which one do we copy it from?</li> |
| <li>If there are <i>n</i> copies of an element in the relevant |
| input range, and the output range will contain fewer copies (say |
| <i>m</i>) which ones do we choose? The first <i>m</i>, or the last |
| <i>m</i>, or something else?</li> |
| <li>Are these operations stable? That is, does a run of equivalent |
| elements appear in the output range in the same order as as it |
| appeared in the input range(s)?</li> |
| </ul> |
| |
| <p> |
| The standard should either answer these questions, or explicitly |
| say that the answers are unspecified. I prefer the former option, |
| since, as far as I know, all existing implementations behave the |
| same way. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to the end of 25.3.5.2 [set.union] paragraph 5:</p> |
| <blockquote><p> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to |
| each other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, then max(<i>m</i>, <i>n</i>) of these elements |
| will be copied to the output range: all <i>m</i> of these elements |
| from [first1, last1), and the last max(<i>n-m</i>, 0) of them from |
| [first2, last2), in that order. |
| </p></blockquote> |
| |
| <p>Add the following to the end of 25.3.5.3 [set.intersection] paragraph 5:</p> |
| <blockquote><p> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to each |
| other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, the first min(<i>m</i>, <i>n</i>) of those |
| elements from [first1, last1) are copied to the output range. |
| </p></blockquote> |
| |
| <p>Add a new paragraph, <b>Notes</b>, after 25.3.5.4 [set.difference] |
| paragraph 4:</p> |
| <blockquote><p> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to each |
| other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, the last max(<i>m-n</i>, 0) elements from |
| [first1, last1) are copied to the output range. |
| </p></blockquote> |
| |
| <p>Add a new paragraph, <b>Notes</b>, after 25.3.5.5 [set.symmetric.difference] |
| paragraph 4:</p> |
| <blockquote><p> |
| If [first1, last1) contains <i>m</i> elements that are equivalent to |
| each other and [first2, last2) contains <i>n</i> elements that are |
| equivalent to them, then |<i>m - n</i>| of those elements will be |
| copied to the output range: the last <i>m - n</i> of these elements |
| from [first1, last1) if <i>m</i> > <i>n</i>, and the last <i>n - |
| m</i> of these elements from [first2, last2) if <i>m</i> < <i>n</i>. |
| </p></blockquote> |
| |
| <p><i>[Santa Cruz: it's believed that this language is clearer than |
| what's in the Standard. However, it's also believed that the |
| Standard may already make these guarantees (although not quite in |
| these words). Bill and Howard will check and see whether they think |
| that some or all of these changes may be redundant. If so, we may |
| close this issue as NAD.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>For simple cases, these descriptions are equivalent to what's |
| already in the Standard. For more complicated cases, they describe |
| the behavior of existing implementations.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="292"></a>292. effects of a.copyfmt (a)</h3> |
| <p><b>Section:</b> 27.4.4.2 [basic.ios.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-01-05</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.ios.members">active issues</a> in [basic.ios.members].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.ios.members">issues</a> in [basic.ios.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The Effects clause of the member function <tt>copyfmt()</tt> in |
| 27.4.4.2, p15 doesn't consider the case where the left-hand side |
| argument is identical to the argument on the right-hand side, that is |
| <tt>(this == &rhs)</tt>. If the two arguments are identical there |
| is no need to copy any of the data members or call any callbacks |
| registered with <tt>register_callback()</tt>. Also, as Howard Hinnant |
| points out in message c++std-lib-8149 it appears to be incorrect to |
| allow the object to fire <tt>erase_event</tt> followed by |
| <tt>copyfmt_event</tt> since the callback handling the latter event |
| may inadvertently attempt to access memory freed by the former. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Effects clause in 27.4.4.2, p15 from</p> |
| |
| <blockquote><p> |
| <b>-15- Effects:</b>Assigns to the member objects of <tt>*this</tt> |
| the corresponding member objects of <tt>rhs</tt>, except that... |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| <b>-15- Effects:</b>If <tt>(this == &rhs)</tt> does nothing. Otherwise |
| assigns to the member objects of <tt>*this</tt> the corresponding member |
| objects of <tt>rhs</tt>, except that... |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="294"></a>294. User defined macros and standard headers</h3> |
| <p><b>Section:</b> 17.4.3.2.1 [macro.names] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> James Kanze <b>Date:</b> 2001-01-11</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Paragraph 2 of 17.4.3.2.1 [macro.names] reads: "A |
| translation unit that includes a header shall not contain any macros |
| that define names declared in that header." As I read this, it |
| would mean that the following program is legal:</p> |
| |
| <pre> #define npos 3.14 |
| #include <sstream> |
| </pre> |
| |
| <p>since npos is not defined in <sstream>. It is, however, defined |
| in <string>, and it is hard to imagine an implementation in |
| which <sstream> didn't include <string>.</p> |
| |
| <p>I think that this phrase was probably formulated before it was |
| decided that a standard header may freely include other standard |
| headers. The phrase would be perfectly appropriate for C, for |
| example. In light of 17.4.4.1 [res.on.headers] paragraph 1, however, |
| it isn't stringent enough.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>For 17.4.3.2.1 [macro.names], replace the current wording, which reads:</p> |
| <blockquote> |
| <p>Each name defined as a macro in a header is reserved to the |
| implementation for any use if the translation unit includes |
| the header.168)</p> |
| |
| <p>A translation unit that includes a header shall not contain any |
| macros that define names declared or defined in that header. Nor shall |
| such a translation unit define macros for names lexically |
| identical to keywords.</p> |
| |
| <p>168) It is not permissible to remove a library macro definition by |
| using the #undef directive.</p> |
| </blockquote> |
| |
| <p>with the wording:</p> |
| |
| <blockquote> |
| <p>A translation unit that includes a standard library header shall not |
| #define or #undef names declared in any standard library header.</p> |
| |
| <p>A translation unit shall not #define or #undef names lexically |
| identical to keywords.</p> |
| </blockquote> |
| |
| <p><i>[Lillehammer: Beman provided new wording]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="295"></a>295. Is abs defined in <cmath>?</h3> |
| <p><b>Section:</b> 26.7 [c.math] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Jens Maurer <b>Date:</b> 2001-01-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#c.math">issues</a> in [c.math].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 80 lists the contents of the <cmath> header. It does not |
| list <tt>abs()</tt>. However, 26.5, paragraph 6, which lists added |
| signatures present in <cmath>, does say that several overloads |
| of <tt>abs()</tt> should be defined in <cmath>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add <tt>abs</tt> to Table 80. Also, remove the parenthetical list |
| of functions "(abs(), div(), rand(), srand())" from 26.5 [numarray], |
| paragraph 1. |
| </p> |
| |
| <p><i>[Copenhagen: Modified proposed resolution so that it also gets |
| rid of that vestigial list of functions in paragraph 1.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>All this DR does is fix a typo; it's uncontroversial. A |
| separate question is whether we're doing the right thing in |
| putting some overloads in <cmath> that we aren't also |
| putting in <cstdlib>. That's issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#323">323</a>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="297"></a>297. const_mem_fun_t<>::argument_type should be const T*</h3> |
| <p><b>Section:</b> 20.6.8 [logical.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-01-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The class templates <tt>const_mem_fun_t</tt> in 20.5.8, p8 and |
| <tt>const_mem_fun1_t</tt> |
| in 20.5.8, p9 derive from <tt>unary_function<T*, S></tt>, and |
| <tt>binary_function<T*, |
| A, S></tt>, respectively. Consequently, their <tt>argument_type</tt>, and |
| <tt>first_argument_type</tt> |
| members, respectively, are both defined to be <tt>T*</tt> (non-const). |
| However, their function call member operator takes a <tt>const T*</tt> |
| argument. It is my opinion that <tt>argument_type</tt> should be <tt>const |
| T*</tt> instead, so that one can easily refer to it in generic code. The |
| example below derived from existing code fails to compile due to the |
| discrepancy: |
| </p> |
| |
| <p><tt>template <class T></tt> |
| <br><tt>void foo (typename T::argument_type arg) // #1</tt> |
| <br><tt>{</tt> |
| <br><tt> typename T::result_type (T::*pf) (typename |
| T::argument_type) |
| const = // #2</tt> |
| <br><tt> &T::operator();</tt> |
| <br><tt>}</tt> |
| </p> |
| |
| <p><tt>struct X { /* ... */ };</tt></p> |
| |
| <p><tt>int main ()</tt> |
| <br><tt>{</tt> |
| <br><tt> const X x;</tt> |
| <br><tt> foo<std::const_mem_fun_t<void, X> |
| >(&x); |
| // #3</tt> |
| <br><tt>}</tt> |
| </p> |
| |
| <p>#1 <tt>foo()</tt> takes a plain unqualified <tt>X*</tt> as an argument |
| <br>#2 the type of the pointer is incompatible with the type of the member |
| function |
| <br>#3 the address of a constant being passed to a function taking a non-const |
| <tt>X*</tt> |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the top portion of the definition of the class template |
| const_mem_fun_t in 20.5.8, p8 |
| </p> |
| <p><tt>template <class S, class T> class const_mem_fun_t</tt> |
| <br><tt> : public |
| unary_function<T*, S> {</tt> |
| </p> |
| <p>with</p> |
| <p><tt>template <class S, class T> class const_mem_fun_t</tt> |
| <br><tt> : public |
| unary_function<<b>const</b> T*, S> {</tt> |
| </p> |
| <p>Also replace the top portion of the definition of the class template |
| const_mem_fun1_t in 20.5.8, p9</p> |
| <p><tt>template <class S, class T, class A> class const_mem_fun1_t</tt> |
| <br><tt> : public |
| binary_function<T*, A, S> {</tt> |
| </p> |
| <p>with</p> |
| <p><tt>template <class S, class T, class A> class const_mem_fun1_t</tt> |
| <br><tt> : public |
| binary_function<<b>const</b> T*, A, S> {</tt> |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This is simply a contradiction: the <tt>argument_type</tt> typedef, |
| and the argument type itself, are not the same.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="298"></a>298. ::operator delete[] requirement incorrect/insufficient</h3> |
| <p><b>Section:</b> 18.5.1.2 [new.delete.array] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> John A. Pedretti <b>Date:</b> 2001-01-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The default behavior of <tt>operator delete[]</tt> described in 18.5.1.2, p12 - |
| namely that for non-null value of <i>ptr</i>, the operator reclaims storage |
| allocated by the earlier call to the default <tt>operator new[]</tt> - is not |
| correct in all cases. Since the specified <tt>operator new[]</tt> default |
| behavior is to call <tt>operator new</tt> (18.5.1.2, p4, p8), which can be |
| replaced, along with <tt>operator delete</tt>, by the user, to implement their |
| own memory management, the specified default behavior of<tt> operator |
| delete[]</tt> must be to call <tt>operator delete</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.5.1.2, p12 from</p> |
| <blockquote><p> |
| <b>-12-</b> <b>Default behavior:</b></p> |
| <ul> |
| <li> |
| For a null value of <i><tt>ptr</tt></i> , does nothing. |
| </li> |
| <li> |
| Any other value of <i><tt>ptr</tt></i> shall be a value returned |
| earlier by a call to the default <tt>operator new[](std::size_t)</tt>. |
| [Footnote: The value must not have been invalidated by an intervening |
| call to <tt>operator delete[](void*)</tt> (17.4.3.8 [res.on.arguments]). |
| --- end footnote] |
| For such a non-null value of <i><tt>ptr</tt></i> , reclaims storage |
| allocated by the earlier call to the default <tt>operator new[]</tt>. |
| </li> |
| </ul> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| <b>-12-</b> <b>Default behavior: </b>Calls <tt>operator |
| delete(</tt><i>ptr</i>) |
| or <tt>operator delete(<i>ptr</i>, std::nothrow)</tt> respectively. |
| </p></blockquote> |
| <p>and expunge paragraph 13.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="300"></a>300. list::merge() specification incomplete</h3> |
| <p><b>Section:</b> 23.2.4.4 [list.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> John Pedretti <b>Date:</b> 2001-01-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.ops">issues</a> in [list.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The "Effects" clause for list::merge() (23.2.4.4 [list.ops], p23) |
| appears to be incomplete: it doesn't cover the case where the argument |
| list is identical to *this (i.e., this == &x). The requirement in the |
| note in p24 (below) is that x be empty after the merge which is surely |
| unintended in this case. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.4.4 [list.ops], replace paragraps 23-25 with:</p> |
| <blockquote> |
| <p> |
| 23 Effects: if (&x == this) does nothing; otherwise, merges the two |
| sorted ranges [begin(), end()) and [x.begin(), x.end()). The result |
| is a range in which the elements will be sorted in non-decreasing |
| order according to the ordering defined by comp; that is, for every |
| iterator i in the range other than the first, the condition comp(*i, |
| *(i - 1)) will be false. |
| </p> |
| |
| <p> |
| 24 Notes: Stable: if (&x != this), then for equivalent elements in the |
| two original ranges, the elements from the original range [begin(), |
| end()) always precede the elements from the original range [x.begin(), |
| x.end()). If (&x != this) the range [x.begin(), x.end()) is empty |
| after the merge. |
| </p> |
| |
| <p> |
| 25 Complexity: At most size() + x.size() - 1 applications of comp if |
| (&x ! = this); otherwise, no applications of comp are performed. If |
| an exception is thrown other than by a comparison there are no |
| effects. |
| </p> |
| |
| </blockquote> |
| |
| <p><i>[Copenhagen: The original proposed resolution did not fix all of |
| the problems in 23.2.4.4 [list.ops], p22-25. Three different |
| paragraphs (23, 24, 25) describe the effects of <tt>merge</tt>. |
| Changing p23, without changing the other two, appears to introduce |
| contradictions. Additionally, "merges the argument list into the |
| list" is excessively vague.]</i></p> |
| |
| |
| <p><i>[Post-Curaçao: Robert Klarer provided new wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="301"></a>301. basic_string template ctor effects clause omits allocator argument</h3> |
| <p><b>Section:</b> 21.3.1 [string.require] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-01-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.require">issues</a> in [string.require].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The effects clause for the basic_string template ctor in 21.3.1, p15 |
| leaves out the third argument of type Allocator. I believe this to be |
| a mistake. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace</p> |
| |
| <blockquote> |
| <p><b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral |
| type, equivalent to</p> |
| |
| <blockquote><p><tt>basic_string(static_cast<size_type>(begin), |
| static_cast<value_type>(end))</tt></p></blockquote> |
| </blockquote> |
| |
| <p>with</p> |
| |
| <blockquote> |
| <p><b>-15- Effects:</b> If <i><tt>InputIterator</tt></i> is an integral |
| type, equivalent to</p> |
| |
| <blockquote><p><tt>basic_string(static_cast<size_type>(begin), |
| static_cast<value_type>(end), <b>a</b>)</tt></p></blockquote> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="303"></a>303. Bitset input operator underspecified</h3> |
| <p><b>Section:</b> 23.3.5.3 [bitset.operators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2001-02-05</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 23.3.5.3, we are told that <tt>bitset</tt>'s input operator |
| "Extracts up to <i>N</i> (single-byte) characters from |
| <i>is</i>.", where <i>is</i> is a stream of type |
| <tt>basic_istream<charT, traits></tt>. |
| </p> |
| |
| <p> |
| The standard does not say what it means to extract single byte |
| characters from a stream whose character type, <tt>charT</tt>, is in |
| general not a single-byte character type. Existing implementations |
| differ. |
| </p> |
| |
| <p> |
| A reasonable solution will probably involve <tt>widen()</tt> and/or |
| <tt>narrow()</tt>, since they are the supplied mechanism for |
| converting a single character between <tt>char</tt> and |
| arbitrary <tt>charT</tt>. |
| </p> |
| |
| <p>Narrowing the input characters is not the same as widening the |
| literals <tt>'0'</tt> and <tt>'1'</tt>, because there may be some |
| locales in which more than one wide character maps to the narrow |
| character <tt>'0'</tt>. Narrowing means that alternate |
| representations may be used for bitset input, widening means that |
| they may not be.</p> |
| |
| <p>Note that for numeric input, <tt>num_get<></tt> |
| (22.2.2.1.2/8) compares input characters to widened version of narrow |
| character literals.</p> |
| |
| <p>From Pete Becker, in c++std-lib-8224:</p> |
| <blockquote> |
| <p> |
| Different writing systems can have different representations for the |
| digits that represent 0 and 1. For example, in the Unicode representation |
| of the Devanagari script (used in many of the Indic languages) the digit 0 |
| is 0x0966, and the digit 1 is 0x0967. Calling narrow would translate those |
| into '0' and '1'. But Unicode also provides the ASCII values 0x0030 and |
| 0x0031 for for the Latin representations of '0' and '1', as well as code |
| points for the same numeric values in several other scripts (Tamil has no |
| character for 0, but does have the digits 1-9), and any of these values |
| would also be narrowed to '0' and '1'. |
| </p> |
| |
| <p>...</p> |
| |
| <p> |
| It's fairly common to intermix both native and Latin |
| representations of numbers in a document. So I think the rule has to be |
| that if a wide character represents a digit whose value is 0 then the bit |
| should be cleared; if it represents a digit whose value is 1 then the bit |
| should be set; otherwise throw an exception. So in a Devanagari locale, |
| both 0x0966 and 0x0030 would clear the bit, and both 0x0967 and 0x0031 |
| would set it. Widen can't do that. It would pick one of those two values, |
| and exclude the other one. |
| </p> |
| |
| </blockquote> |
| |
| <p>From Jens Maurer, in c++std-lib-8233:</p> |
| |
| <blockquote> |
| <p> |
| Whatever we decide, I would find it most surprising if |
| bitset conversion worked differently from int conversion |
| with regard to alternate local representations of |
| numbers. |
| </p> |
| |
| <p>Thus, I think the options are:</p> |
| <ul> |
| <li> Have a new defect issue for 22.2.2.1.2/8 so that it will |
| require the use of narrow().</li> |
| |
| <li> Have a defect issue for bitset() which describes clearly |
| that widen() is to be used.</li> |
| </ul> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Replace the first two sentences of paragraph 5 with:</p> |
| |
| <blockquote><p> |
| Extracts up to <i>N</i> characters from <i>is</i>. Stores these |
| characters in a temporary object <i>str</i> of type |
| <tt>basic_string<charT, traits></tt>, then evaluates the |
| expression <tt><i>x</i> = bitset<N>(<i>str</i>)</tt>. |
| </p></blockquote> |
| |
| <p>Replace the third bullet item in paragraph 5 with:</p> |
| <ul><li> |
| the next input character is neither <tt><i>is</i>.widen(0)</tt> |
| nor <tt><i>is</i>.widen(1)</tt> (in which case the input character |
| is not extracted). |
| </li></ul> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Input for <tt>bitset</tt> should work the same way as numeric |
| input. Using <tt>widen</tt> does mean that alternative digit |
| representations will not be recognized, but this was a known |
| consequence of the design choice.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="305"></a>305. Default behavior of codecvt<wchar_t, char, mbstate_t>::length()</h3> |
| <p><b>Section:</b> 22.2.1.5 [locale.codecvt.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2001-01-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt.byname">issues</a> in [locale.codecvt.byname].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>22.2.1.5/3 introduces codecvt in part with:</p> |
| |
| <blockquote><p> |
| codecvt<wchar_t,char,mbstate_t> converts between the native |
| character sets for tiny and wide characters. Instantiations on |
| mbstate_t perform conversion between encodings known to the library |
| implementor. |
| </p></blockquote> |
| |
| <p>But 22.2.1.5.2/10 describes do_length in part with:</p> |
| |
| <blockquote><p> |
| ... codecvt<wchar_t, char, mbstate_t> ... return(s) the lesser of max and |
| (from_end-from). |
| </p></blockquote> |
| |
| <p> |
| The semantics of do_in and do_length are linked. What one does must |
| be consistent with what the other does. 22.2.1.5/3 leads me to |
| believe that the vendor is allowed to choose the algorithm that |
| codecvt<wchar_t,char,mbstate_t>::do_in performs so that it makes |
| his customers happy on a given platform. But 22.2.1.5.2/10 explicitly |
| says what codecvt<wchar_t,char,mbstate_t>::do_length must |
| return. And thus indirectly specifies the algorithm that |
| codecvt<wchar_t,char,mbstate_t>::do_in must perform. I believe |
| that this is not what was intended and is a defect. |
| </p> |
| |
| <p>Discussion from the -lib reflector: |
| |
| <br>This proposal would have the effect of making the semantics of |
| all of the virtual functions in <tt>codecvt<wchar_t, char, |
| mbstate_t></tt> implementation specified. Is that what we want, or |
| do we want to mandate specific behavior for the base class virtuals |
| and leave the implementation specified behavior for the codecvt_byname |
| derived class? The tradeoff is that former allows implementors to |
| write a base class that actually does something useful, while the |
| latter gives users a way to get known and specified---albeit |
| useless---behavior, and is consistent with the way the standard |
| handles other facets. It is not clear what the original intention |
| was.</p> |
| |
| <p> |
| Nathan has suggest a compromise: a character that is a widened version |
| of the characters in the basic execution character set must be |
| converted to a one-byte sequence, but there is no such requirement |
| for characters that are not part of the basic execution character set. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 22.2.1.5.2/5 from: |
| </p> |
| <p> |
| The instantiations required in Table 51 (lib.locale.category), namely |
| codecvt<wchar_t,char,mbstate_t> and |
| codecvt<char,char,mbstate_t>, store no characters. Stores no more |
| than (to_limit-to) destination elements. It always leaves the to_next |
| pointer pointing one beyond the last element successfully stored. |
| </p> |
| <p> |
| to: |
| </p> |
| <p> |
| Stores no more than (to_limit-to) destination elements, and leaves the |
| to_next pointer pointing one beyond the last element successfully |
| stored. codecvt<char,char,mbstate_t> stores no characters. |
| </p> |
| |
| <p>Change 22.2.1.5.2/10 from:</p> |
| |
| <blockquote><p> |
| -10- Returns: (from_next-from) where from_next is the largest value in |
| the range [from,from_end] such that the sequence of values in the |
| range [from,from_next) represents max or fewer valid complete |
| characters of type internT. The instantiations required in Table 51 |
| (21.1.1.1.1), namely codecvt<wchar_t, char, mbstate_t> and |
| codecvt<char, char, mbstate_t>, return the lesser of max and |
| (from_end-from). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| -10- Returns: (from_next-from) where from_next is the largest value in |
| the range [from,from_end] such that the sequence of values in the range |
| [from,from_next) represents max or fewer valid complete characters of |
| type internT. The instantiation codecvt<char, char, mbstate_t> returns |
| the lesser of max and (from_end-from). |
| </p></blockquote> |
| |
| <p><i>[Redmond: Nathan suggested an alternative resolution: same as |
| above, but require that, in the default encoding, a character from the |
| basic execution character set would map to a single external |
| character. The straw poll was 8-1 in favor of the proposed |
| resolution.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The default encoding should be whatever users of a given platform |
| would expect to be the most natural. This varies from platform to |
| platform. In many cases there is a preexisting C library, and users |
| would expect the default encoding to be whatever C uses in the default |
| "C" locale. We could impose a guarantee like the one Nathan suggested |
| (a character from the basic execution character set must map to a |
| single external character), but this would rule out important |
| encodings that are in common use: it would rule out JIS, for |
| example, and it would rule out a fixed-width encoding of UCS-4.</p> |
| |
| <p><i>[Curaçao: fixed rationale typo at the request of Ichiro Koshida; |
| "shift-JIS" changed to "JIS".]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="306"></a>306. offsetof macro and non-POD types</h3> |
| <p><b>Section:</b> 18.1 [support.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 2001-02-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#support.types">issues</a> in [support.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Spliced together from reflector messages c++std-lib-8294 and -8295:</p> |
| |
| <p>18.1, paragraph 5, reads: "The macro <tt>offsetof</tt> |
| accepts a restricted set of <i>type</i> arguments in this |
| International Standard. <i>type</i> shall be a POD structure or a POD |
| union (clause 9). The result of applying the offsetof macro to a field |
| that is a static data member or a function member is |
| undefined."</p> |
| |
| <p>For the POD requirement, it doesn't say "no diagnostic |
| required" or "undefined behavior". I read 1.4 [intro.compliance], paragraph 1, to mean that a diagnostic is required. |
| It's not clear whether this requirement was intended. While it's |
| possible to provide such a diagnostic, the extra complication doesn't |
| seem to add any value. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.1, paragraph 5, to "If <i>type</i> is not a POD |
| structure or a POD union the results are undefined."</p> |
| |
| <p><i>[Copenhagen: straw poll was 7-4 in favor. It was generally |
| agreed that requiring a diagnostic was inadvertent, but some LWG |
| members thought that diagnostics should be required whenever |
| possible.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="307"></a>307. Lack of reference typedefs in container adaptors</h3> |
| <p><b>Section:</b> 23.2.4 [list] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2001-03-13</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>From reflector message c++std-lib-8330. See also lib-8317.</p> |
| |
| <p> |
| The standard is currently inconsistent in 23.2.4.2 [list.capacity] |
| paragraph 1 and 23.2.4.3 [list.modifiers] paragraph 1. |
| 23.2.3.3/1, for example, says: |
| </p> |
| |
| <blockquote><p> |
| -1- Any sequence supporting operations back(), push_back() and pop_back() |
| can be used to instantiate stack. In particular, vector (lib.vector), list |
| (lib.list) and deque (lib.deque) can be used. |
| </p></blockquote> |
| |
| <p>But this is false: vector<bool> can not be used, because the |
| container adaptors return a T& rather than using the underlying |
| container's reference type.</p> |
| |
| <p>This is a contradiction that can be fixed by:</p> |
| |
| <ol> |
| <li>Modifying these paragraphs to say that vector<bool> |
| is an exception.</li> |
| <li>Removing the vector<bool> specialization.</li> |
| <li>Changing the return types of stack and priority_queue to use |
| reference typedef's.</li> |
| </ol> |
| |
| <p> |
| I propose 3. This does not preclude option 2 if we choose to do it |
| later (see issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#96">96</a>); the issues are independent. Option |
| 3 offers a small step towards support for proxied containers. This |
| small step fixes a current contradiction, is easy for vendors to |
| implement, is already implemented in at least one popular lib, and |
| does not break any code. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Summary: Add reference and const_reference typedefs to queue, |
| priority_queue and stack. Change return types of "value_type&" to |
| "reference". Change return types of "const value_type&" to |
| "const_reference". Details:</p> |
| |
| <p>Change 23.2.3.1/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit queue(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| value_type& front() { return c.front(); } |
| const value_type& front() const { return c.front(); } |
| value_type& back() { return c.back(); } |
| const value_type& back() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_front(); } |
| }; |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit queue(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| reference front() { return c.front(); } |
| const_reference front() const { return c.front(); } |
| reference back() { return c.back(); } |
| const_reference back() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_front(); } |
| }; |
| </pre> |
| |
| <p>Change 23.2.3.2/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = vector<T>, |
| class Compare = less<typename Container::value_type> > |
| class priority_queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| Compare comp; |
| |
| public: |
| explicit priority_queue(const Compare& x = Compare(), |
| const Container& = Container()); |
| template <class InputIterator> |
| priority_queue(InputIterator first, InputIterator last, |
| const Compare& x = Compare(), |
| const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| const value_type& top() const { return c.front(); } |
| void push(const value_type& x); |
| void pop(); |
| }; |
| // no equality is provided |
| } |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = vector<T>, |
| class Compare = less<typename Container::value_type> > |
| class priority_queue { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| Compare comp; |
| |
| public: |
| explicit priority_queue(const Compare& x = Compare(), |
| const Container& = Container()); |
| template <class InputIterator> |
| priority_queue(InputIterator first, InputIterator last, |
| const Compare& x = Compare(), |
| const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| const_reference top() const { return c.front(); } |
| void push(const value_type& x); |
| void pop(); |
| }; |
| // no equality is provided |
| } |
| </pre> |
| |
| <p>And change 23.2.3.3/1 from:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class stack { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit stack(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| value_type& top() { return c.back(); } |
| const value_type& top() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_back(); } |
| }; |
| |
| template <class T, class Container> |
| bool operator==(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator< (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator!=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator> (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator>=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator<=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| } |
| </pre> |
| |
| <p>to:</p> |
| |
| <pre> namespace std { |
| template <class T, class Container = deque<T> > |
| class stack { |
| public: |
| typedef typename Container::value_type value_type; |
| typedef typename Container::reference reference; |
| typedef typename Container::const_reference const_reference; |
| typedef typename Container::size_type size_type; |
| typedef Container container_type; |
| protected: |
| Container c; |
| |
| public: |
| explicit stack(const Container& = Container()); |
| |
| bool empty() const { return c.empty(); } |
| size_type size() const { return c.size(); } |
| reference top() { return c.back(); } |
| const_reference top() const { return c.back(); } |
| void push(const value_type& x) { c.push_back(x); } |
| void pop() { c.pop_back(); } |
| }; |
| |
| template <class T, class Container> |
| bool operator==(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator< (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator!=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator> (const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator>=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| template <class T, class Container> |
| bool operator<=(const stack<T, Container>& x, |
| const stack<T, Container>& y); |
| } |
| </pre> |
| |
| <p><i>[Copenhagen: This change was discussed before the IS was released |
| and it was deliberately not adopted. Nevertheless, the LWG believes |
| (straw poll: 10-2) that it is a genuine defect.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="308"></a>308. Table 82 mentions unrelated headers</h3> |
| <p><b>Section:</b> 27 [input.output] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-03-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.output">issues</a> in [input.output].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 82 in section 27 mentions the header <cstdlib> for String |
| streams (27.7 [string.streams]) and the headers <cstdio> and |
| <cwchar> for File streams (27.8 [file.streams]). It's not clear |
| why these headers are mentioned in this context since they do not |
| define any of the library entities described by the |
| subclauses. According to 17.4.1.1 [contents], only such headers |
| are to be listed in the summary. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove <cstdlib> and <cwchar> from |
| Table 82.</p> |
| |
| <p><i>[Copenhagen: changed the proposed resolution slightly. The |
| original proposed resolution also said to remove <cstdio> from |
| Table 82. However, <cstdio> is mentioned several times within |
| section 27.8 [file.streams], including 27.8.2 [c.files].]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="310"></a>310. Is errno a macro?</h3> |
| <p><b>Section:</b> 17.4.1.2 [headers], 19.3 [errno] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 2001-03-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#headers">issues</a> in [headers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Exactly how should errno be declared in a conforming C++ header? |
| </p> |
| |
| <p> |
| The C standard says in 7.1.4 that it is unspecified whether errno is a |
| macro or an identifier with external linkage. In some implementations |
| it can be either, depending on compile-time options. (E.g., on |
| Solaris in multi-threading mode, errno is a macro that expands to a |
| function call, but is an extern int otherwise. "Unspecified" allows |
| such variability.) |
| </p> |
| |
| <p>The C++ standard:</p> |
| <ul> |
| <li>17.4.1.2 says in a note that errno must be macro in C. (false)</li> |
| <li>17.4.3.1.3 footnote 166 says errno is reserved as an external |
| name (true), and implies that it is an identifier.</li> |
| <li>19.3 simply lists errno as a macro (by what reasoning?) and goes |
| on to say that the contents of of C++ <errno.h> are the |
| same as in C, begging the question.</li> |
| <li>C.2, table 95 lists errno as a macro, without comment.</li> |
| </ul> |
| |
| <p>I find no other references to errno.</p> |
| |
| <p>We should either explicitly say that errno must be a macro, even |
| though it need not be a macro in C, or else explicitly leave it |
| unspecified. We also need to say something about namespace std. |
| A user who includes <cerrno> needs to know whether to write |
| <tt>errno</tt>, or <tt>::errno</tt>, or <tt>std::errno</tt>, or |
| else <cerrno> is useless.</p> |
| |
| <p>Two acceptable fixes:</p> |
| <ul> |
| <li><p>errno must be a macro. This is trivially satisfied by adding<br> |
| #define errno (::std::errno)<br> |
| to the headers if errno is not already a macro. You then always |
| write errno without any scope qualification, and it always expands |
| to a correct reference. Since it is always a macro, you know to |
| avoid using errno as a local identifer.</p></li> |
| <li><p>errno is in the global namespace. This fix is inferior, because |
| ::errno is not guaranteed to be well-formed.</p></li> |
| </ul> |
| |
| <p><i>[ |
| This issue was first raised in 1999, but it slipped through |
| the cracks. |
| ]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the Note in section 17.4.1.2p5 from</p> |
| |
| <blockquote><p> |
| Note: the names defined as macros in C include the following: |
| assert, errno, offsetof, setjmp, va_arg, va_end, and va_start. |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| Note: the names defined as macros in C include the following: |
| assert, offsetof, setjmp, va_arg, va_end, and va_start. |
| </p></blockquote> |
| |
| <p>In section 19.3, change paragraph 2 from</p> |
| |
| <blockquote><p> |
| The contents are the same as the Standard C library header |
| <errno.h>. |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| The contents are the same as the Standard C library header |
| <errno.h>, except that errno shall be defined as a macro. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>C++ must not leave it up to the implementation to decide whether or |
| not a name is a macro; it must explicitly specify exactly which names |
| are required to be macros. The only one that really works is for it |
| to be a macro.</p> |
| |
| <p><i>[Curaçao: additional rationale added.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="311"></a>311. Incorrect wording in basic_ostream class synopsis</h3> |
| <p><b>Section:</b> 27.6.2.1 [ostream] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andy Sawyer <b>Date:</b> 2001-03-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream">issues</a> in [ostream].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>In 27.6.2.1 [ostream], the synopsis of class basic_ostream says:</p> |
| |
| <pre> // partial specializationss |
| template<class traits> |
| basic_ostream<char,traits>& operator<<( basic_ostream<char,traits>&, |
| const char * ); |
| </pre> |
| |
| <p>Problems:</p> |
| <ul> |
| <li>Too many 's's at the end of "specializationss" </li> |
| <li>This is an overload, not a partial specialization</li> |
| </ul> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the synopsis in 27.6.2.1 [ostream], remove the |
| <i>// partial specializationss</i> comment. Also remove the same |
| comment (correctly spelled, but still incorrect) from the synopsis in |
| 27.6.2.6.4 [ostream.inserters.character]. |
| </p> |
| |
| <p><i>[ |
| Pre-Redmond: added 27.6.2.6.4 [ostream.inserters.character] because of Martin's |
| comment in c++std-lib-8939. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="312"></a>312. Table 27 is missing headers</h3> |
| <p><b>Section:</b> 20 [utilities] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-03-29</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Table 27 in section 20 lists the header <memory> (only) for |
| Memory (lib.memory) but neglects to mention the headers |
| <cstdlib> and <cstring> that are discussed in 20.5.5 [meta.rel].</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add <cstdlib> and <cstring> to Table 27, in the same row |
| as <memory>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="315"></a>315. Bad "range" in list::unique complexity</h3> |
| <p><b>Section:</b> 23.2.4.4 [list.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andy Sawyer <b>Date:</b> 2001-05-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.ops">issues</a> in [list.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 23.2.4.4 [list.ops], Para 21 describes the complexity of |
| list::unique as: "If the range (last - first) is not empty, exactly |
| (last - first) -1 applications of the corresponding predicate, |
| otherwise no applications of the predicate)". |
| </p> |
| |
| <p> |
| "(last - first)" is not a range. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the "range" from (last - first) to [first, last). |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="316"></a>316. Vague text in Table 69</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-05-04</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Table 69 says this about a_uniq.insert(t):</p> |
| |
| <blockquote><p> |
| inserts t if and only if there is no element in the container with key |
| equivalent to the key of t. The bool component of the returned pair |
| indicates whether the insertion takes place and the iterator component of the |
| pair points to the element with key equivalent to the key of t. |
| </p></blockquote> |
| |
| <p>The description should be more specific about exactly how the bool component |
| indicates whether the insertion takes place.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in question to</p> |
| |
| <blockquote><p> |
| ...The bool component of the returned pair is true if and only if the insertion |
| takes place... |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="317"></a>317. Instantiation vs. specialization of facets</h3> |
| <p><b>Section:</b> 22 [localization] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-05-04</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#localization">issues</a> in [localization].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The localization section of the standard refers to specializations of |
| the facet templates as instantiations even though the required facets |
| are typically specialized rather than explicitly (or implicitly) |
| instantiated. In the case of ctype<char> and |
| ctype_byname<char> (and the wchar_t versions), these facets are |
| actually required to be specialized. The terminology should be |
| corrected to make it clear that the standard doesn't mandate explicit |
| instantiation (the term specialization encompasses both explicit |
| instantiations and specializations). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In the following paragraphs, replace all occurrences of the word |
| instantiation or instantiations with specialization or specializations, |
| respectively: |
| </p> |
| |
| <blockquote><p> |
| 22.1.1.1.1, p4, Table 52, 22.2.1.1, p2, 22.2.1.5, p3, 22.2.1.5.1, p5, |
| 22.2.1.5.2, p10, 22.2.2, p2, 22.2.3.1, p1, 22.2.3.1.2, p1, p2 and p3, |
| 22.2.4.1, p1, 22.2.4.1.2, p1, 22,2,5, p1, 22,2,6, p2, 22.2.6.3.2, p7, and |
| Footnote 242. |
| </p></blockquote> |
| |
| <p>And change the text in 22.1.1.1.1, p4 from</p> |
| |
| <blockquote><p> |
| An implementation is required to provide those instantiations |
| for facet templates identified as members of a category, and |
| for those shown in Table 52: |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| An implementation is required to provide those specializations... |
| </p></blockquote> |
| |
| <p><i>[Nathan will review these changes, and will look for places where |
| explicit specialization is necessary.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This is a simple matter of outdated language. The language to |
| describe templates was clarified during the standardization process, |
| but the wording in clause 22 was never updated to reflect that |
| change.</p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="318"></a>318. Misleading comment in definition of numpunct_byname</h3> |
| <p><b>Section:</b> 22.2.3.2 [locale.numpunct.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-05-12</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The definition of the numpunct_byname template contains the following |
| comment:</p> |
| |
| <pre> namespace std { |
| template <class charT> |
| class numpunct_byname : public numpunct<charT> { |
| // this class is specialized for char and wchar_t. |
| ... |
| </pre> |
| |
| <p>There is no documentation of the specializations and it seems |
| conceivable that an implementation will not explicitly specialize the |
| template at all, but simply provide the primary template.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the comment from the text in 22.2.3.2 and from the proposed |
| resolution of library issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#228">228</a>.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="319"></a>319. Storage allocation wording confuses "Required behavior", "Requires"</h3> |
| <p><b>Section:</b> 18.5.1.1 [new.delete.single], 18.5.1.2 [new.delete.array] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2001-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#new.delete.single">issues</a> in [new.delete.single].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The standard specifies 17.3.1.3 [structure.specifications] that "Required |
| behavior" elements describe "the semantics of a function definition |
| provided by either the implementation or a C++ program."</p> |
| |
| <p>The standard specifies 17.3.1.3 [structure.specifications] that "Requires" |
| elements describe "the preconditions for calling the function."</p> |
| |
| <p>In the sections noted below, the current wording specifies |
| "Required Behavior" for what are actually preconditions, and thus |
| should be specified as "Requires".</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 18.5.1.1 [new.delete.single] Para 12 Change:</p> |
| <blockquote> |
| <p>Required behavior: accept a value of ptr that is null or that was |
| returned by an earlier call ...</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Requires: the value of ptr is null or the value returned by an |
| earlier call ...</p> |
| </blockquote> |
| |
| <p>In 18.5.1.2 [new.delete.array] Para 11 Change:</p> |
| <blockquote> |
| <p>Required behavior: accept a value of ptr that is null or that was |
| returned by an earlier call ...</p> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p>Requires: the value of ptr is null or the value returned by an |
| earlier call ...</p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="320"></a>320. list::assign overspecified</h3> |
| <p><b>Section:</b> 23.2.4.1 [list.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2001-05-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.cons">issues</a> in [list.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 23.2.4.1 [list.cons], paragraphs 6-8 specify that list assign (both forms) have |
| the "effects" of a call to erase followed by a call to insert. |
| </p> |
| |
| <p> |
| I would like to document that implementers have the freedom to implement |
| assign by other methods, as long as the end result is the same and the |
| exception guarantee is as good or better than the basic guarantee. |
| </p> |
| |
| <p> |
| The motivation for this is to use T's assignment operator to recycle |
| existing nodes in the list instead of erasing them and reallocating |
| them with new values. It is also worth noting that, with careful |
| coding, most common cases of assign (everything but assignment with |
| true input iterators) can elevate the exception safety to strong if |
| T's assignment has a nothrow guarantee (with no extra memory cost). |
| Metrowerks does this. However I do not propose that this subtlety be |
| standardized. It is a QoI issue. </p> |
| |
| <p>Existing practise: |
| Metrowerks and SGI recycle nodes, Dinkumware and Rogue Wave don't. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 23.2.4.1 [list.cons]/7 from:</p> |
| |
| <blockquote> |
| <p>Effects:</p> |
| |
| <pre> erase(begin(), end()); |
| insert(begin(), first, last); |
| </pre> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Replaces the contents of the list with the range [first, last).</p> |
| </blockquote> |
| |
| <p>In 23.1.3 [sequence.reqmts], in Table 67 (sequence requirements), |
| add two new rows:</p> |
| <pre> a.assign(i,j) void pre: i,j are not iterators into a. |
| Replaces elements in a with a copy |
| of [i, j). |
| |
| a.assign(n,t) void pre: t is not a reference into a. |
| Replaces elements in a with n copies |
| of t. |
| </pre> |
| |
| <p>Change 23.2.4.1 [list.cons]/8 from:</p> |
| |
| <blockquote> |
| <p>Effects:</p> |
| <pre> erase(begin(), end()); |
| insert(begin(), n, t); |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| |
| <blockquote> |
| <p>Effects: Replaces the contents of the list with n copies of t.</p> |
| </blockquote> |
| |
| <p><i>[Redmond: Proposed resolution was changed slightly. Previous |
| version made explicit statement about exception safety, which wasn't |
| consistent with the way exception safety is expressed elsewhere. |
| Also, the change in the sequence requirements is new. Without that |
| change, the proposed resolution would have required that assignment of |
| a subrange would have to work. That too would have been |
| overspecification; it would effectively mandate that assignment use a |
| temporary. Howard provided wording. |
| ]</i></p> |
| |
| |
| <p><i>[Curaçao: Made editorial improvement in wording; changed |
| "Replaces elements in a with copies of elements in [i, j)." |
| with "Replaces the elements of a with a copy of [i, j)." |
| Changes not deemed serious enough to requre rereview.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="321"></a>321. Typo in num_get</h3> |
| <p><b>Section:</b> 22.2.2.1.2 [facet.num.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Kevin Djang <b>Date:</b> 2001-05-17</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 22.2.2.1.2 at p7 states that "A length specifier is added to |
| the conversion function, if needed, as indicated in Table 56." |
| However, Table 56 uses the term "length modifier", not "length |
| specifier". |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 22.2.2.1.2 at p7, change the text "A length specifier is added ..." |
| to be "A length modifier is added ..." |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>C uses the term "length modifier". We should be consistent.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="322"></a>322. iterator and const_iterator should have the same value type</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2001-05-17</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It's widely assumed that, if X is a container, |
| iterator_traits<X::iterator>::value_type and |
| iterator_traits<X::const_iterator>::value_type should both be |
| X::value_type. However, this is nowhere stated. The language in |
| Table 65 is not precise about the iterators' value types (it predates |
| iterator_traits), and could even be interpreted as saying that |
| iterator_traits<X::const_iterator>::value_type should be "const |
| X::value_type". |
| </p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#279">279</a>.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In Table 65 ("Container Requirements"), change the return type for |
| X::iterator to "iterator type whose value type is T". Change the |
| return type for X::const_iterator to "constant iterator type whose |
| value type is T".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This belongs as a container requirement, rather than an iterator |
| requirement, because the whole notion of iterator/const_iterator |
| pairs is specific to containers' iterator. |
| </p> |
| <p> |
| It is existing practice that (for example) |
| iterator_traits<list<int>::const_iterator>::value_type |
| is "int", rather than "const int". This is consistent with |
| the way that const pointers are handled: the standard already |
| requires that iterator_traits<const int*>::value_type is int. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="324"></a>324. Do output iterators have value types?</h3> |
| <p><b>Section:</b> 24.1.2 [output.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2001-06-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#output.iterators">issues</a> in [output.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>Table 73 suggests that output iterators have value types. It |
| requires the expression "*a = t". Additionally, although Table 73 |
| never lists "a = t" or "X(a) = t" in the "expressions" column, it |
| contains a note saying that "a = t" and "X(a) = t" have equivalent |
| (but nowhere specified!) semantics.</p> |
| |
| <p>According to 24.1/9, t is supposed to be "a value of value type |
| T":</p> |
| |
| <blockquote><p> |
| In the following sections, a and b denote values of X, n denotes a |
| value of the difference type Distance, u, tmp, and m denote |
| identifiers, r denotes a value of X&, t denotes a value of |
| value type T. |
| </p></blockquote> |
| |
| <p>Two other parts of the standard that are relevant to whether |
| output iterators have value types:</p> |
| |
| <ul> |
| <li>24.1/1 says "All iterators i support the expression *i, |
| resulting in a value of some class, enumeration, or built-in type |
| T, called the value type of the iterator".</li> |
| |
| <li> |
| 24.3.1/1, which says "In the case of an output iterator, the types |
| iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type are both defined as void." |
| </li> |
| </ul> |
| |
| <p>The first of these passages suggests that "*i" is supposed to |
| return a useful value, which contradicts the note in 24.1.2/2 saying |
| that the only valid use of "*i" for output iterators is in an |
| expression of the form "*i = t". The second of these passages appears |
| to contradict Table 73, because it suggests that "*i"'s return value |
| should be void. The second passage is also broken in the case of a an |
| iterator type, like non-const pointers, that satisfies both the output |
| iterator requirements and the forward iterator requirements.</p> |
| |
| <p>What should the standard say about <tt>*i</tt>'s return value when |
| i is an output iterator, and what should it say about that t is in the |
| expression "*i = t"? Finally, should the standard say anything about |
| output iterators' pointer and reference types?</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>24.1 p1, change</p> |
| |
| <blockquote> |
| <p>All iterators <tt>i</tt> support the expression <tt>*i</tt>, resulting |
| in a value of some class, enumeration, or built-in type <tt>T</tt>, |
| called the value type of the iterator.</p> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <p>All input iterators <tt>i</tt> support the expression <tt>*i</tt>, |
| resulting in a value of some class, enumeration, or built-in type |
| <tt>T</tt>, called the value type of the iterator. All output |
| iterators support the expression <tt>*i = o</tt> where <tt>o</tt> is a |
| value of some type that is in the set of types that are <i>writable</i> to |
| the particular iterator type of <tt>i</tt>. |
| </p> |
| </blockquote> |
| |
| <p>24.1 p9, add</p> |
| |
| <blockquote> |
| <p><tt>o</tt> denotes a value of some type that is writable to the |
| output iterator. |
| </p> |
| </blockquote> |
| |
| <p>Table 73, change</p> |
| |
| <blockquote> |
| <pre>*a = t |
| </pre> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <pre>*r = o |
| </pre> |
| </blockquote> |
| |
| <p>and change</p> |
| |
| <blockquote> |
| <pre>*r++ = t |
| </pre> |
| </blockquote> |
| |
| <p>to</p> |
| |
| <blockquote> |
| <pre>*r++ = o |
| </pre> |
| </blockquote> |
| |
| <p><i>[post-Redmond: Jeremy provided wording]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered two options: change all of the language that |
| seems to imply that output iterators have value types, thus making it |
| clear that output iterators have no value types, or else define value |
| types for output iterator consistently. The LWG chose the former |
| option, because it seems clear that output iterators were never |
| intended to have value types. This was a deliberate design decision, |
| and any language suggesting otherwise is simply a mistake.</p> |
| |
| <p>A future revision of the standard may wish to revisit this design |
| decision.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="325"></a>325. Misleading text in moneypunct<>::do_grouping</h3> |
| <p><b>Section:</b> 22.2.6.3.2 [locale.moneypunct.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-07-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.moneypunct.virtuals">issues</a> in [locale.moneypunct.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The Returns clause in 22.2.6.3.2, p3 says about |
| moneypunct<charT>::do_grouping() |
| </p> |
| |
| <blockquote><p> |
| Returns: A pattern defined identically as the result of |
| numpunct<charT>::do_grouping().241) |
| </p></blockquote> |
| |
| <p>Footnote 241 then reads</p> |
| |
| <blockquote><p> |
| This is most commonly the value "\003" (not "3"). |
| </p></blockquote> |
| |
| <p> |
| The returns clause seems to imply that the two member functions must |
| return an identical value which in reality may or may not be true, |
| since the facets are usually implemented in terms of struct std::lconv |
| and return the value of the grouping and mon_grouping, respectively. |
| The footnote also implies that the member function of the moneypunct |
| facet (rather than the overridden virtual functions in moneypunct_byname) |
| most commonly return "\003", which contradicts the C standard which |
| specifies the value of "" for the (most common) C locale. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the text in Returns clause in 22.2.6.3.2, p3 with the following:</p> |
| |
| <blockquote><p> |
| Returns: A pattern defined identically as, but not necessarily |
| equal to, the result of numpunct<charT>::do_grouping().241) |
| </p></blockquote> |
| |
| <p>and replace the text in Footnote 241 with the following:</p> |
| |
| <blockquote><p> |
| To specify grouping by 3s the value is "\003", not "3". |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The fundamental problem is that the description of the locale facet |
| virtuals serves two purposes: describing the behavior of the base |
| class, and describing the meaning of and constraints on the behavior |
| in arbitrary derived classes. The new wording makes that separation a |
| little bit clearer. The footnote (which is nonnormative) is not |
| supposed to say what the grouping is in the "C" locale or in any other |
| locale. It is just a reminder that the values are interpreted as small |
| integers, not ASCII characters. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="327"></a>327. Typo in time_get facet in table 52</h3> |
| <p><b>Section:</b> 22.1.1.1.1 [locale.category] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Tiki Wan <b>Date:</b> 2001-07-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.category">issues</a> in [locale.category].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#447">447</a></p> |
| <p><b>Discussion:</b></p> |
| <p>The <tt>wchar_t</tt> versions of <tt>time_get</tt> and |
| <tt>time_get_byname</tt> are listed incorrectly in table 52, |
| required instantiations. In both cases the second template |
| parameter is given as OutputIterator. It should instead be |
| InputIterator, since these are input facets.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In table 52, required instantiations, in |
| 22.1.1.1.1 [locale.category], change</p> |
| <pre> time_get<wchar_t, OutputIterator> |
| time_get_byname<wchar_t, OutputIterator> |
| </pre> |
| <p>to</p> |
| <pre> time_get<wchar_t, InputIterator> |
| time_get_byname<wchar_t, InputIterator> |
| </pre> |
| |
| <p><i>[Redmond: Very minor change in proposed resolution. Original had |
| a typo, wchart instead of wchar_t.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="328"></a>328. Bad sprintf format modifier in money_put<>::do_put()</h3> |
| <p><b>Section:</b> 22.2.6.2.2 [locale.money.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-07-07</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The sprintf format string , "%.01f" (that's the digit one), in the |
| description of the do_put() member functions of the money_put facet in |
| 22.2.6.2.2, p1 is incorrect. First, the f format specifier is wrong |
| for values of type long double, and second, the precision of 01 |
| doesn't seem to make sense. What was most likely intended was |
| "%.0Lf"., that is a precision of zero followed by the L length |
| modifier.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the format string to "%.0Lf".</p> |
| |
| |
| <p><b>Rationale:</b></p><p>Fixes an obvious typo</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="329"></a>329. vector capacity, reserve and reallocation</h3> |
| <p><b>Section:</b> 23.2.6.2 [vector.capacity], 23.2.6.4 [vector.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Anthony Williams <b>Date:</b> 2001-07-13</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.capacity">issues</a> in [vector.capacity].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| There is an apparent contradiction about which circumstances can cause |
| a reallocation of a vector in Section 23.2.6.2 [vector.capacity] and |
| section 23.2.6.4 [vector.modifiers]. |
| </p> |
| |
| <p>23.2.6.2 [vector.capacity],p5 says:</p> |
| <blockquote><p> |
| Notes: Reallocation invalidates all the references, pointers, and iterators |
| referring to the elements in the sequence. It is guaranteed that no |
| reallocation takes place during insertions that happen after a call to |
| reserve() until the time when an insertion would make the size of the vector |
| greater than the size specified in the most recent call to reserve(). |
| </p></blockquote> |
| |
| <p>Which implies if I do</p> |
| |
| <pre> std::vector<int> vec; |
| vec.reserve(23); |
| vec.reserve(0); |
| vec.insert(vec.end(),1); |
| </pre> |
| |
| <p>then the implementation may reallocate the vector for the insert, |
| as the size specified in the previous call to reserve was zero.</p> |
| |
| <p>However, the previous paragraphs (23.2.6.2 [vector.capacity], p1-2) state:</p> |
| <blockquote> |
| <p> |
| (capacity) Returns: The total number of elements the vector |
| can hold without requiring reallocation |
| </p> |
| <p> |
| ...After reserve(), capacity() is greater or equal to the |
| argument of reserve if reallocation happens; and equal to the previous value |
| of capacity() otherwise... |
| </p> |
| </blockquote> |
| |
| <p> |
| This implies that vec.capacity() is still 23, and so the insert() |
| should not require a reallocation, as vec.size() is 0. This is backed |
| up by 23.2.6.4 [vector.modifiers], p1: |
| </p> |
| <blockquote><p> |
| (insert) Notes: Causes reallocation if the new size is greater than the old |
| capacity. |
| </p></blockquote> |
| |
| <p> |
| Though this doesn't rule out reallocation if the new size is less |
| than the old capacity, I think the intent is clear. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the wording of 23.2.6.2 [vector.capacity] paragraph 5 to:</p> |
| |
| <blockquote><p> |
| Notes: Reallocation invalidates all the references, pointers, and |
| iterators referring to the elements in the sequence. It is guaranteed |
| that no reallocation takes place during insertions that happen after a |
| call to reserve() until the time when an insertion would make the size |
| of the vector greater than the value of capacity(). |
| </p></blockquote> |
| |
| <p><i>[Redmond: original proposed resolution was modified slightly. In |
| the original, the guarantee was that there would be no reallocation |
| until the size would be greater than the value of capacity() after the |
| most recent call to reserve(). The LWG did not believe that the |
| "after the most recent call to reserve()" added any useful |
| information.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>There was general agreement that, when reserve() is called twice in |
| succession and the argument to the second invocation is smaller than |
| the argument to the first, the intent was for the second invocation to |
| have no effect. Wording implying that such cases have an effect on |
| reallocation guarantees was inadvertant.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="331"></a>331. bad declaration of destructor for ios_base::failure</h3> |
| <p><b>Section:</b> 27.4.2.1.1 [ios::failure] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> PremAnand M. Rao <b>Date:</b> 2001-08-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios::failure">issues</a> in [ios::failure].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| With the change in 17.4.4.9 [res.on.exception.handling] to state |
| "An implementation may strengthen the exception-specification for a |
| non-virtual function by removing listed exceptions." |
| (issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#119">119</a>) |
| and the following declaration of ~failure() in ios_base::failure |
| </p> |
| <pre> namespace std { |
| class ios_base::failure : public exception { |
| public: |
| ... |
| virtual ~failure(); |
| ... |
| }; |
| } |
| </pre> |
| <p>the class failure cannot be implemented since in 18.6.1 [type.info] the destructor of class exception has an empty |
| exception specification:</p> |
| <pre> namespace std { |
| class exception { |
| public: |
| ... |
| virtual ~exception() throw(); |
| ... |
| }; |
| } |
| </pre> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove the declaration of ~failure().</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution is consistent with the way that destructors |
| of other classes derived from <tt>exception</tt> are handled.</p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="333"></a>333. does endl imply synchronization with the device?</h3> |
| <p><b>Section:</b> 27.6.2.8 [ostream.manip] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> PremAnand M. Rao <b>Date:</b> 2001-08-27</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>A footnote in 27.6.2.8 [ostream.manip] states:</p> |
| <blockquote><p> |
| [Footnote: The effect of executing cout << endl is to insert a |
| newline character in the output sequence controlled by cout, then |
| synchronize it with any external file with which it might be |
| associated. --- end foonote] |
| </p></blockquote> |
| |
| <p> |
| Does the term "file" here refer to the external device? |
| This leads to some implementation ambiguity on systems with fully |
| buffered files where a newline does not cause a flush to the device. |
| </p> |
| |
| <p> |
| Choosing to sync with the device leads to significant performance |
| penalties for each call to endl, while not sync-ing leads to |
| errors under special circumstances. |
| </p> |
| |
| <p> |
| I could not find any other statement that explicitly defined |
| the behavior one way or the other. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove footnote 300 from section 27.6.2.8 [ostream.manip].</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>We already have normative text saying what <tt>endl</tt> does: it |
| inserts a newline character and calls <tt>flush</tt>. This footnote |
| is at best redundant, at worst (as this issue says) misleading, |
| because it appears to make promises about what <tt>flush</tt> |
| does.</p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="334"></a>334. map::operator[] specification forces inefficient implementation</h3> |
| <p><b>Section:</b> 23.3.1.2 [map.access] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andrea Griffini <b>Date:</b> 2001-09-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#map.access">issues</a> in [map.access].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current standard describes map::operator[] using a |
| code example. That code example is however quite |
| inefficient because it requires several useless copies |
| of both the passed key_type value and of default |
| constructed mapped_type instances. |
| My opinion is that was not meant by the comitee to |
| require all those temporary copies. |
| </p> |
| |
| <p>Currently map::operator[] behaviour is specified as: </p> |
| <pre> Returns: |
| (*((insert(make_pair(x, T()))).first)).second. |
| </pre> |
| |
| <p> |
| This specification however uses make_pair that is a |
| template function of which parameters in this case |
| will be deduced being of type const key_type& and |
| const T&. This will create a pair<key_type,T> that |
| isn't the correct type expected by map::insert so |
| another copy will be required using the template |
| conversion constructor available in pair to build |
| the required pair<const key_type,T> instance. |
| </p> |
| |
| <p>If we consider calling of key_type copy constructor |
| and mapped_type default constructor and copy |
| constructor as observable behaviour (as I think we |
| should) then the standard is in this place requiring |
| two copies of a key_type element plus a default |
| construction and two copy construction of a mapped_type |
| (supposing the addressed element is already present |
| in the map; otherwise at least another copy |
| construction for each type). |
| </p> |
| |
| <p>A simple (half) solution would be replacing the description with:</p> |
| <pre> Returns: |
| (*((insert(value_type(x, T()))).first)).second. |
| </pre> |
| |
| <p>This will remove the wrong typed pair construction that |
| requires one extra copy of both key and value.</p> |
| |
| <p>However still the using of map::insert requires temporary |
| objects while the operation, from a logical point of view, |
| doesn't require any. </p> |
| |
| <p>I think that a better solution would be leaving free an |
| implementer to use a different approach than map::insert |
| that, because of its interface, forces default constructed |
| temporaries and copies in this case. |
| The best solution in my opinion would be just requiring |
| map::operator[] to return a reference to the mapped_type |
| part of the contained element creating a default element |
| with the specified key if no such an element is already |
| present in the container. Also a logarithmic complexity |
| requirement should be specified for the operation. |
| </p> |
| |
| <p> |
| This would allow library implementers to write alternative |
| implementations not using map::insert and reaching optimal |
| performance in both cases of the addressed element being |
| present or absent from the map (no temporaries at all and |
| just the creation of a new pair inside the container if |
| the element isn't present). |
| Some implementer has already taken this option but I think |
| that the current wording of the standard rules that as |
| non-conforming. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Replace 23.3.1.2 [map.access] paragraph 1 with |
| </p> |
| <blockquote> |
| <p> |
| -1- Effects: If there is no key equivalent to x in the map, inserts |
| value_type(x, T()) into the map. |
| </p> |
| <p> |
| -2- Returns: A reference to the mapped_type corresponding to x in *this. |
| </p> |
| <p> |
| -3- Complexity: logarithmic. |
| </p> |
| </blockquote> |
| |
| <p><i>[This is the second option mentioned above. Howard provided |
| wording. We may also wish to have a blanket statement somewhere in |
| clause 17 saying that we do not intend the semantics of sample code |
| fragments to be interpreted as specifing exactly how many copies are |
| made. See issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#98">98</a> for a similar problem.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This is the second solution described above; as noted, it is |
| consistent with existing practice. |
| </p> |
| |
| <p>Note that we now need to specify the complexity explicitly, because |
| we are no longer defining <tt>operator[]</tt> in terms of |
| <tt>insert</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="335"></a>335. minor issue with char_traits, table 37</h3> |
| <p><b>Section:</b> 21.1.1 [char.traits.require] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andy Sawyer <b>Date:</b> 2001-09-06</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 37, in 21.1.1 [char.traits.require], descibes char_traits::assign |
| as: |
| </p> |
| <pre> X::assign(c,d) assigns c = d. |
| </pre> |
| |
| <p>And para 1 says:</p> |
| |
| <blockquote><p> |
| [...] c and d denote values of type CharT [...] |
| </p></blockquote> |
| |
| <p> |
| Naturally, if c and d are <i>values</i>, then the assignment is |
| (effectively) meaningless. It's clearly intended that (in the case of |
| assign, at least), 'c' is intended to be a reference type. |
| </p> |
| |
| <p>I did a quick survey of the four implementations I happened to have |
| lying around, and sure enough they all have signatures:</p> |
| <pre> assign( charT&, const charT& ); |
| </pre> |
| |
| <p>(or the equivalent). It's also described this way in Nico's book. |
| (Not to mention the synopses of char_traits<char> in 21.1.3.1 |
| and char_traits<wchar_t> in 21.1.3.2...) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following to 21.1.1 para 1:</p> |
| <blockquote><p> |
| r denotes an lvalue of CharT |
| </p></blockquote> |
| |
| <p>and change the description of assign in the table to:</p> |
| <pre> X::assign(r,d) assigns r = d |
| </pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="336"></a>336. Clause 17 lack of references to deprecated headers</h3> |
| <p><b>Section:</b> 17 [library] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Detlef Vollmann <b>Date:</b> 2001-09-05</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#library">issues</a> in [library].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>From c++std-edit-873:</p> |
| |
| <p>17.4.1.2 [headers], Table 11. In this table, the header |
| <strstream> is missing.</p> |
| |
| <p>This shows a general problem: The whole clause 17 refers quite |
| often to clauses 18 through 27, but D.7 is also a part of the standard |
| library (though a deprecated one).</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>To 17.4.1.2 [headers] Table 11, C++ Library Headers, add |
| "<strstream>".</p> |
| |
| <p>In the following places, change "clauses 17 through 27" to "clauses |
| 17 through 27 and Annex D":</p> |
| |
| <ul> |
| <li>1.2 [intro.refs] Normative references/1/footnote 1</li> |
| <li>1.3 [intro.defs] Definitions/1</li> |
| <li>7 [dcl.dcl] Library introduction/9</li> |
| <li>17.3 [description] Method of description (Informative)/1</li> |
| <li>17.3.2.1.3 [character.seq] Character sequences/1/bullet 2</li> |
| <li>17.3.2.2 [functions.within.classes] Functions within classes/1</li> |
| <li>17.3.2.3 [objects.within.classes] Private members/1/(2 places)</li> |
| <li>17.4 [requirements] Library-wide requirements/1</li> |
| <li>17.4.1.2 [headers] Headers/4</li> |
| <li>17.4.3.5 [replacement.functions] Replacement functions/1</li> |
| <li>17.4.4.3 [global.functions] Global or non-member functions/2</li> |
| <li>17.4.4.7 [protection.within.classes] Protection within classes/1</li> |
| </ul> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="337"></a>337. replace_copy_if's template parameter should be InputIterator</h3> |
| <p><b>Section:</b> 25.2.5 [alg.replace] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Detlef Vollmann <b>Date:</b> 2001-09-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.replace">issues</a> in [alg.replace].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>From c++std-edit-876:</p> |
| |
| <p> |
| In section 25.2.5 [alg.replace] before p4: The name of the first |
| parameter of template replace_copy_if should be "InputIterator" |
| instead of "Iterator". According to 17.3.2.1 [type.descriptions] p1 the |
| parameter name conveys real normative meaning. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change <tt>Iterator</tt> to <tt>InputIterator</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="338"></a>338. is whitespace allowed between `-' and a digit?</h3> |
| <p><b>Section:</b> 22.2 [locale.categories] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-09-17</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#locale.categories">active issues</a> in [locale.categories].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.categories">issues</a> in [locale.categories].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| From Stage 2 processing in 22.2.2.1.2 [facet.num.get.virtuals], p8 and 9 (the |
| original text or the text corrected by the proposed resolution of |
| issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#221">221</a>) it seems clear that no whitespace is allowed |
| within a number, but 22.2.3.1 [locale.numpunct], p2, which gives the |
| format for integer and floating point values, says that whitespace is |
| optional between a plusminus and a sign. |
| </p> |
| |
| <p> |
| The text needs to be clarified to either consistently allow or |
| disallow whitespace between a plusminus and a sign. It might be |
| worthwhile to consider the fact that the C library stdio facility does |
| not permit whitespace embedded in numbers and neither does the C or |
| C++ core language (the syntax of integer-literals is given in 2.13.1 |
| [lex.icon], that of floating-point-literals in 2.13.3 [lex.fcon] of the |
| C++ standard). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the first part of 22.2.3.1 [locale.numpunct] paragraph 2 from:</p> |
| <blockquote> |
| <p> |
| The syntax for number formats is as follows, where <tt>digit</tt> |
| represents the radix set specified by the <tt>fmtflags</tt> argument |
| value, <tt>whitespace</tt> is as determined by the facet |
| <tt>ctype<charT></tt> (22.2.1.1), and <tt>thousands-sep</tt> and |
| <tt>decimal-point</tt> are the results of corresponding |
| <tt>numpunct<charT></tt> members. Integer values have the |
| format: |
| </p> |
| <pre> integer ::= [sign] units |
| sign ::= plusminus [whitespace] |
| plusminus ::= '+' | '-' |
| units ::= digits [thousands-sep units] |
| digits ::= digit [digits] |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <p> |
| The syntax for number formats is as follows, where <tt>digit</tt> |
| represents the radix set specified by the <tt>fmtflags</tt> argument |
| value, and <tt>thousands-sep</tt> and <tt>decimal-point</tt> are the |
| results of corresponding <tt>numpunct<charT></tt> members. |
| Integer values have the format: |
| </p> |
| <pre> integer ::= [sign] units |
| sign ::= plusminus |
| plusminus ::= '+' | '-' |
| units ::= digits [thousands-sep units] |
| digits ::= digit [digits] |
| </pre> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>It's not clear whether the format described in 22.2.3.1 [locale.numpunct] paragraph 2 has any normative weight: nothing in the |
| standard says how, or whether, it's used. However, there's no reason |
| for it to differ gratuitously from the very specific description of |
| numeric processing in 22.2.2.1.2 [facet.num.get.virtuals]. The proposed |
| resolution removes all mention of "whitespace" from that format.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="339"></a>339. definition of bitmask type restricted to clause 27</h3> |
| <p><b>Section:</b> 22.2.1 [category.ctype], 17.3.2.1.2 [bitmask.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-09-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#category.ctype">issues</a> in [category.ctype].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>The ctype_category::mask type is declared to be an enum in 22.2.1 |
| [category.ctype] with p1 then stating that it is a bitmask type, most |
| likely referring to the definition of bitmask type in 17.3.2.1.2 |
| [bitmask.types], p1. However, the said definition only applies to |
| clause 27, making the reference in 22.2.1 somewhat dubious. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Clarify 17.3.2.1.2, p1 by changing the current text from</p> |
| <blockquote><p> |
| Several types defined in clause 27 are bitmask types. Each bitmask type |
| can be implemented as an enumerated type that overloads certain operators, |
| as an integer type, or as a bitset (23.3.5 [template.bitset]). |
| </p></blockquote> |
| <p>to read</p> |
| <blockquote><p> |
| Several types defined in clauses lib.language.support through |
| lib.input.output and Annex D are bitmask types. Each bitmask type can |
| be implemented as an enumerated type that overloads certain operators, |
| as an integer type, or as a bitset (lib.template.bitset). |
| </p></blockquote> |
| |
| <p> |
| Additionally, change the definition in 22.2.1 to adopt the same |
| convention as in clause 27 by replacing the existing text with the |
| following (note, in particluar, the cross-reference to 17.3.2.1.2 in |
| 22.2.1, p1): |
| </p> |
| |
| <blockquote> |
| <p>22.2.1 The ctype category [lib.category.ctype]</p> |
| <pre>namespace std { |
| class ctype_base { |
| public: |
| typedef <b><i>T</i></b> mask; |
| |
| // numeric values are for exposition only. |
| static const mask space = 1 << 0; |
| static const mask print = 1 << 1; |
| static const mask cntrl = 1 << 2; |
| static const mask upper = 1 << 3; |
| static const mask lower = 1 << 4; |
| static const mask alpha = 1 << 5; |
| static const mask digit = 1 << 6; |
| static const mask punct = 1 << 7; |
| static const mask xdigit = 1 << 8; |
| static const mask alnum = alpha | digit; |
| static const mask graph = alnum | punct; |
| }; |
| } |
| </pre> |
| |
| <p>The type <tt>mask</tt> is a bitmask type (17.3.2.1.2 [bitmask.types]).</p> |
| </blockquote> |
| |
| <p><i>[Curaçao: The LWG notes that T above should be bold-italics to be |
| consistent with the rest of the standard.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="340"></a>340. interpretation of <tt>has_facet<Facet>(loc)</tt></h3> |
| <p><b>Section:</b> 22.1.1.1.1 [locale.category] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.category">issues</a> in [locale.category].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It's unclear whether 22.1.1.1.1, p3 says that |
| <tt>has_facet<Facet>(loc)</tt> returns true for any <tt>Facet</tt> |
| from Table 51 or whether it includes Table 52 as well: |
| </p> |
| |
| <blockquote><p> |
| For any locale <tt>loc</tt> either constructed, or returned by |
| locale::classic(), and any facet <tt>Facet</tt> that is a member of a |
| standard category, <tt>has_facet<Facet>(loc)</tt> is true. Each |
| locale member function which takes a <tt>locale::category</tt> |
| argument operates on the corresponding set of facets. |
| </p></blockquote> |
| |
| <p> |
| It seems that it comes down to which facets are considered to be members of a |
| standard category. Intuitively, I would classify all the facets in Table 52 as |
| members of their respective standard categories, but there are an unbounded set |
| of them... |
| </p> |
| |
| <p> |
| The paragraph implies that, for instance, <tt>has_facet<num_put<C, |
| OutputIterator> >(loc)</tt> must always return true. I don't think that's |
| possible. If it were, then <tt>use_facet<num_put<C, OutputIterator> |
| >(loc)</tt> would have to return a reference to a distinct object for each |
| valid specialization of <tt>num_put<C, OutputIteratory></tt>, which is |
| clearly impossible. |
| </p> |
| |
| <p> |
| On the other hand, if none of the facets in Table 52 is a member of a standard |
| category then none of the locale member functions that operate on entire |
| categories of facets will work properly. |
| </p> |
| |
| <p> |
| It seems that what p3 should mention that it's required (permitted?) |
| to hold only for specializations of <tt>Facet</tt> from Table 52 on |
| <tt>C</tt> from the set { <tt>char</tt>, <tt>wchar_t</tt> }, and |
| <tt>InputIterator</tt> and <tt>OutputIterator</tt> from the set of |
| { |
| {i,o}<tt>streambuf_iterator</tt><{<tt>char</tt>,<tt>wchar_t</tt>}<tt>></tt> |
| }. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.1.1.1 [locale.category], paragraph 3, change |
| "that is a member of a standard category" to "shown in Table 51".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The facets in Table 52 are an unbounded set. Locales should not be |
| required to contain an infinite number of facets.</p> |
| |
| <p>It's not necessary to talk about which values of InputIterator and |
| OutputIterator must be supported. Table 51 already contains a |
| complete list of the ones we need.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="341"></a>341. Vector reallocation and swap</h3> |
| <p><b>Section:</b> 23.2.6.2 [vector.capacity] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Anthony Williams <b>Date:</b> 2001-09-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.capacity">issues</a> in [vector.capacity].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>It is a common idiom to reduce the capacity of a vector by swapping it with |
| an empty one:</p> |
| <pre> std::vector<SomeType> vec; |
| // fill vec with data |
| std::vector<SomeType>().swap(vec); |
| // vec is now empty, with minimal capacity |
| </pre> |
| |
| <p>However, the wording of 23.2.6.2 [vector.capacity]paragraph 5 prevents |
| the capacity of a vector being reduced, following a call to |
| reserve(). This invalidates the idiom, as swap() is thus prevented |
| from reducing the capacity. The proposed wording for issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#329">329</a> does not affect this. Consequently, the example above |
| requires the temporary to be expanded to cater for the contents of |
| vec, and the contents be copied across. This is a linear-time |
| operation.</p> |
| |
| <p>However, the container requirements state that swap must have constant |
| complexity (23.1 [container.requirements] note to table 65).</p> |
| |
| <p>This is an important issue, as reallocation affects the validity of |
| references and iterators.</p> |
| |
| <p>If the wording of 23.2.4.2p5 is taken to be the desired intent, then |
| references and iterators remain valid after a call to swap, if they refer to |
| an element before the new end() of the vector into which they originally |
| pointed, in which case they refer to the element at the same index position. |
| Iterators and references that referred to an element whose index position |
| was beyond the new end of the vector are invalidated.</p> |
| |
| <p>If the note to table 65 is taken as the desired intent, then there are two |
| possibilities with regard to iterators and references:</p> |
| |
| <ol> |
| <li>All Iterators and references into both vectors are invalidated.</li> |
| <li>Iterators and references into either vector remain valid, and remain |
| pointing to the same element. Consequently iterators and references that |
| referred to one vector now refer to the other, and vice-versa.</li> |
| </ol> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a new paragraph after 23.2.6.2 [vector.capacity] paragraph 5:</p> |
| <blockquote> |
| <pre> void swap(vector<T,Allocator>& x); |
| </pre> |
| <p><b>Effects:</b> Exchanges the contents and capacity() of <tt>*this</tt> |
| with that of <tt>x</tt>.</p> |
| <p><b>Complexity:</b> Constant time.</p> |
| </blockquote> |
| |
| <p><i>[This solves the problem reported for this issue. We may also |
| have a problem with a circular definition of swap() for other |
| containers.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| swap should be constant time. The clear intent is that it should just |
| do pointer twiddling, and that it should exchange all properties of |
| the two vectors, including their reallocation guarantees. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="345"></a>345. type tm in <cwchar></h3> |
| <p><b>Section:</b> 21.5 [c.strings] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Clark Nelson <b>Date:</b> 2001-10-19</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#c.strings">issues</a> in [c.strings].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>C99, and presumably amendment 1 to C90, specify that <wchar.h> |
| declares struct tm as an incomplete type. However, table 48 in 21.5 |
| [c.strings] does not mention the type tm as being declared in |
| <cwchar>. Is this omission intentional or accidental? |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In section 21.5 [c.strings], add "tm" to table 48.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="346"></a>346. Some iterator member functions should be const</h3> |
| <p><b>Section:</b> 24.1 [iterator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Jeremy Siek <b>Date:</b> 2001-10-20</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#iterator.requirements">active issues</a> in [iterator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iterator.requirements">issues</a> in [iterator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Iterator member functions and operators that do not change the state |
| of the iterator should be defined as const member functions or as |
| functions that take iterators either by const reference or by |
| value. The standard does not explicitly state which functions should |
| be const. Since this a fairly common mistake, the following changes |
| are suggested to make this explicit.</p> |
| |
| <p>The tables almost indicate constness properly through naming: r |
| for non-const and a,b for const iterators. The following changes |
| make this more explicit and also fix a couple problems.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 24.1 [iterator.requirements] Change the first section of p9 from |
| "In the following sections, a and b denote values of X..." to |
| "In the following sections, a and b denote values of type const X...".</p> |
| |
| <p>In Table 73, change</p> |
| <pre> a->m U& ... |
| </pre> |
| |
| <p>to</p> |
| |
| <pre> a->m const U& ... |
| r->m U& ... |
| </pre> |
| |
| <p>In Table 73 expression column, change</p> |
| |
| <pre> *a = t |
| </pre> |
| |
| <p>to</p> |
| |
| <pre> *r = t |
| </pre> |
| |
| <p><i>[Redmond: The container requirements should be reviewed to see if |
| the same problem appears there.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="347"></a>347. locale::category and bitmask requirements</h3> |
| <p><b>Section:</b> 22.1.1.1.1 [locale.category] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger, Nathan Myers <b>Date:</b> 2001-10-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.category">issues</a> in [locale.category].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 22.1.1.1.1 [locale.category] paragraph 1, the category members |
| are described as bitmask elements. In fact, the bitmask requirements |
| in 17.3.2.1.2 [bitmask.types] don't seem quite right: <tt>none</tt> |
| and <tt>all</tt> are bitmask constants, not bitmask elements.</p> |
| |
| <p>In particular, the requirements for <tt>none</tt> interact poorly |
| with the requirement that the LC_* constants from the C library must |
| be recognizable as C++ locale category constants. LC_* values should |
| not be mixed with these values to make category values.</p> |
| |
| <p>We have two options for the proposed resolution. Informally: |
| option 1 removes the requirement that LC_* values be recognized as |
| category arguments. Option 2 changes the category type so that this |
| requirement is implementable, by allowing <tt>none</tt> to be some |
| value such as 0x1000 instead of 0.</p> |
| |
| <p>Nathan writes: "I believe my proposed resolution [Option 2] merely |
| re-expresses the status quo more clearly, without introducing any |
| changes beyond resolving the DR.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace the first two paragraphs of 22.1.1.1 [locale.types] with:</p> |
| <blockquote> |
| <pre> typedef int category; |
| </pre> |
| |
| <p>Valid category values include the <tt>locale</tt> member bitmask |
| elements <tt>collate</tt>, <tt>ctype</tt>, <tt>monetary</tt>, |
| <tt>numeric</tt>, <tt>time</tt>, and <tt>messages</tt>, each of which |
| represents a single locale category. In addition, <tt>locale</tt> member |
| bitmask constant <tt>none</tt> is defined as zero and represents no |
| category. And locale member bitmask constant <tt>all</tt> is defined such that |
| the expression</p> |
| <pre> (collate | ctype | monetary | numeric | time | messages | all) == all |
| </pre> |
| <p> |
| is <tt>true</tt>, and represents the union of all categories. Further |
| the expression <tt>(X | Y)</tt>, where <tt>X</tt> and <tt>Y</tt> each |
| represent a single category, represents the union of the two |
| categories. |
| </p> |
| |
| <p> |
| <tt>locale</tt> member functions expecting a <tt>category</tt> |
| argument require one of the <tt>category</tt> values defined above, or |
| the union of two or more such values. Such a <tt>category</tt> |
| argument identifies a set of locale categories. Each locale category, |
| in turn, identifies a set of locale facets, including at least those |
| shown in Table 51: |
| </p> |
| </blockquote> |
| <p><i>[Curaçao: need input from locale experts.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| |
| <p>The LWG considered, and rejected, an alternate proposal (described |
| as "Option 2" in the discussion). The main reason for rejecting it |
| was that library implementors were concerened about implementation |
| difficult, given that getting a C++ library to work smoothly with a |
| separately written C library is already a delicate business. Some |
| library implementers were also concerned about the issue of adding |
| extra locale categories.</p> |
| |
| <blockquote> |
| <p><b>Option 2:</b> <br> |
| Replace the first paragraph of 22.1.1.1 [locale.types] with:</p> |
| <blockquote> |
| <p> |
| Valid category values include the enumerated values. In addition, the |
| result of applying commutative operators | and & to any two valid |
| values is valid, and results in the setwise union and intersection, |
| respectively, of the argument categories. The values <tt>all</tt> and |
| <tt>none</tt> are defined such that for any valid value <tt>cat</tt>, the |
| expressions <tt>(cat | all == all)</tt>, <tt>(cat & all == cat)</tt>, |
| <tt>(cat | none == cat)</tt> and <tt>(cat & none == none)</tt> are |
| true. For non-equal values <tt>cat1</tt> and <tt>cat2</tt> of the |
| remaining enumerated values, <tt>(cat1 & cat2 == none)</tt> is true. |
| For any valid categories <tt>cat1</tt> and <tt>cat2</tt>, the result |
| of <tt>(cat1 & ~cat2)</tt> is valid, and equals the setwise union of |
| those categories found in <tt>cat1</tt> but not found in <tt>cat2</tt>. |
| [Footnote: it is not required that <tt>all</tt> equal the setwise union |
| of the other enumerated values; implementations may add extra categories.] |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="349"></a>349. Minor typographical error in ostream_iterator</h3> |
| <p><b>Section:</b> 24.5.2 [ostream.iterator] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andy Sawyer <b>Date:</b> 2001-10-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>24.5.2 [lib.ostream.iterator] states:</p> |
| <pre> [...] |
| |
| private: |
| // basic_ostream<charT,traits>* out_stream; exposition only |
| // const char* delim; exposition only |
| </pre> |
| |
| <p>Whilst it's clearly marked "exposition only", I suspect 'delim' |
| should be of type 'const charT*'.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 24.5.2 [ostream.iterator], replace <tt>const char* delim</tt> with |
| <tt>const charT* delim</tt>. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="352"></a>352. missing fpos requirements</h3> |
| <p><b>Section:</b> 21.1.2 [char.traits.typedefs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2001-12-02</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <i>(1)</i> |
| There are no requirements on the <tt>stateT</tt> template parameter of |
| <tt>fpos</tt> listed in 27.4.3. The interface appears to require that |
| the type be at least Assignable and CopyConstructible (27.4.3.1, p1), |
| and I think also DefaultConstructible (to implement the operations in |
| Table 88). |
| </p> |
| <p> |
| 21.1.2, p3, however, only requires that |
| <tt>char_traits<charT>::state_type</tt> meet the requirements of |
| CopyConstructible types. |
| </p> |
| <p> |
| <i>(2)</i> |
| Additionally, the <tt>stateT</tt> template argument has no |
| corresponding typedef in fpos which might make it difficult to use in |
| generic code. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Modify 21.1.2, p4 from |
| </p> |
| <p> |
| Requires: <tt>state_type</tt> shall meet the requirements of |
| CopyConstructible types (20.1.3). |
| </p> |
| <p> |
| Requires: state_type shall meet the requirements of Assignable |
| (23.1, p4), CopyConstructible (20.1.3), and |
| DefaultConstructible (20.1.4) types. |
| </p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG feels this is two issues, as indicated above. The first is |
| a defect---std::basic_fstream is unimplementable without these |
| additional requirements---and the proposed resolution fixes it. The |
| second is questionable; who would use that typedef? The class |
| template fpos is used only in a very few places, all of which know the |
| state type already. Unless motivation is provided, the second should |
| be considered NAD.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="354"></a>354. Associative container lower/upper bound requirements</h3> |
| <p><b>Section:</b> 23.1.4 [associative.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Hans Aberg <b>Date:</b> 2001-12-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#associative.reqmts">issues</a> in [associative.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Discussions in the thread "Associative container lower/upper bound |
| requirements" on comp.std.c++ suggests that there is a defect in the |
| C++ standard, Table 69 of section 23.1.2, "Associative containers", |
| [lib.associative.reqmts]. It currently says:</p> |
| |
| <blockquote> |
| <p> |
| a.find(k): returns an iterator pointing to an element with the key equivalent to |
| k, or a.end() if such an element is not found. |
| </p> |
| |
| <p> |
| a.lower_bound(k): returns an iterator pointing to the first element with |
| key not less than k. |
| </p> |
| |
| <p> |
| a.upper_bound(k): returns an iterator pointing to the first element with |
| key greater than k. |
| </p> |
| </blockquote> |
| |
| <p> |
| We have "or a.end() if such an element is not found" for |
| <tt>find</tt>, but not for <tt>upper_bound</tt> or |
| <tt>lower_bound</tt>. As the text stands, one would be forced to |
| insert a new element into the container and return an iterator to that |
| in case the sought iterator does not exist, which does not seem to be |
| the intention (and not possible with the "const" versions). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change Table 69 of section 23.1.4 [associative.reqmts] indicated entries |
| to:</p> |
| |
| <blockquote> |
| <p> |
| a.lower_bound(k): returns an iterator pointing to the first element with |
| key not less than k, or a.end() if such an element is not found. |
| </p> |
| |
| <p> |
| a.upper_bound(k): returns an iterator pointing to the first element with |
| key greater than k, or a.end() if such an element is not found. |
| </p> |
| </blockquote> |
| |
| <p><i>[Curaçao: LWG reviewed PR.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="355"></a>355. Operational semantics for a.back()</h3> |
| <p><b>Section:</b> 23.1.3 [sequence.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Yaroslav Mironov <b>Date:</b> 2002-01-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>Table 68 "Optional Sequence Operations" in 23.1.1/12 |
| specifies operational semantics for "a.back()" as |
| "*--a.end()", which may be ill-formed <i>[because calling |
| operator-- on a temporary (the return) of a built-in type is |
| ill-formed]</i>, provided a.end() returns a simple pointer rvalue |
| (this is almost always the case for std::vector::end(), for |
| example). Thus, the specification is not only incorrect, it |
| demonstrates a dangerous construct: "--a.end()" may |
| successfully compile and run as intended, but after changing the type |
| of the container or the mode of compilation it may produce |
| compile-time error. </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the specification in table 68 "Optional Sequence |
| Operations" in 23.1.1/12 for "a.back()" from</p> |
| |
| |
| <blockquote><pre>*--a.end() |
| </pre></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><pre> { iterator tmp = a.end(); --tmp; return *tmp; } |
| </pre></blockquote> |
| |
| <p>and the specification for "a.pop_back()" from</p> |
| |
| <blockquote><pre>a.erase(--a.end()) |
| </pre></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><pre> { iterator tmp = a.end(); --tmp; a.erase(tmp); } |
| </pre></blockquote> |
| |
| <p><i>[Curaçao: LWG changed PR from "{ X::iterator tmp = |
| a.end(); return *--tmp; }" to "*a.rbegin()", and from |
| "{ X::iterator tmp = a.end(); a.erase(--tmp); }" to |
| "a.erase(rbegin())".]</i></p> |
| |
| |
| <p><i>[There is a second possible defect; table 68 "Optional |
| Sequence Operations" in the "Operational Semantics" |
| column uses operations present only in the "Reversible |
| Container" requirements, yet there is no stated dependency |
| between these separate requirements tables. Ask in Santa Cruz if the |
| LWG would like a new issue opened.]</i></p> |
| |
| |
| <p><i>[Santa Cruz: the proposed resolution is even worse than what's in |
| the current standard: erase is undefined for reverse iterator. If |
| we're going to make the change, we need to define a temporary and |
| use operator--. Additionally, we don't know how prevalent this is: |
| do we need to make this change in more than one place? Martin has |
| volunteered to review the standard and see if this problem occurs |
| elsewhere.]</i></p> |
| |
| |
| <p><i>[Oxford: Matt provided new wording to address the concerns raised |
| in Santa Cruz. It does not appear that this problem appears |
| anywhere else in clauses 23 or 24.]</i></p> |
| |
| |
| <p><i>[Kona: In definition of operational semantics of back(), change |
| "*tmp" to "return *tmp;"]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="358"></a>358. interpreting <tt>thousands_sep</tt> after a <tt>decimal_point</tt></h3> |
| <p><b>Section:</b> 22.2.2.1.2 [facet.num.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-03-12</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#facet.num.get.virtuals">active issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#facet.num.get.virtuals">issues</a> in [facet.num.get.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I don't think <tt>thousands_sep</tt> is being treated correctly after |
| decimal_point has been seen. Since grouping applies only to the |
| integral part of the number, the first such occurrence should, IMO, |
| terminate Stage 2. (If it does not terminate it, then 22.2.2.1.2, p12 |
| and 22.2.3.1.2, p3 need to explain how <tt>thousands_sep</tt> is to be |
| interpreted in the fractional part of a number.) |
| </p> |
| |
| <p> |
| The easiest change I can think of that resolves this issue would be |
| something like below. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first sentence of 22.2.2.1.2, p9 from |
| </p> |
| |
| <blockquote><p> |
| If discard is true then the position of the character is |
| remembered, but the character is otherwise ignored. If it is not |
| discarded, then a check is made to determine if c is allowed as |
| the next character of an input field of the conversion specifier |
| returned by stage 1. If so it is accumulated. |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| If <tt>discard</tt> is true, then if <tt>'.'</tt> has not yet been |
| accumulated, then the position of the character is remembered, but |
| the character is otherwise ignored. Otherwise, if <tt>'.'</tt> has |
| already been accumulated, the character is discarded and Stage 2 |
| terminates. ... |
| </p></blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>We believe this reflects the intent of the Standard. Thousands sep |
| characters after the decimal point are not useful in any locale. |
| Some formatting conventions do group digits that follow the decimal |
| point, but they usually introduce a different grouping character |
| instead of reusing the thousand sep character. If we want to add |
| support for such conventions, we need to do so explicitly.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="359"></a>359. num_put<>::do_put (..., bool) undocumented</h3> |
| <p><b>Section:</b> 22.2.2.2.1 [facet.num.put.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-03-12</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>22.2.2.2.1, p1:</p> |
| |
| <pre> iter_type put (iter_type out, ios_base& str, char_type fill, |
| bool val) const; |
| ... |
| |
| 1 Returns: do_put (out, str, fill, val). |
| </pre> |
| |
| <p>AFAICS, the behavior of do_put (..., bool) is not documented anywhere, |
| however, 22.2.2.2.2, p23:</p> |
| |
| <blockquote> |
| <pre>iter_type put (iter_type out, ios_base& str, char_type fill, |
| bool val) const; |
| </pre> |
| |
| |
| <p>Effects: If (str.flags() & ios_base::boolalpha) == 0 then do |
| out = do_put(out, str, fill, (int)val) |
| Otherwise do</p> |
| <pre> string_type s = |
| val ? use_facet<ctype<charT> >(loc).truename() |
| : use_facet<ctype<charT> >(loc).falsename(); |
| </pre> |
| <p>and then insert the characters of s into out. <i>out</i>.</p> |
| </blockquote> |
| |
| <p> |
| This means that the bool overload of <tt>do_put()</tt> will never be called, |
| which contradicts the first paragraph. Perhaps the declaration |
| should read <tt>do_put()</tt>, and not <tt>put()</tt>? |
| </p> |
| |
| <p> |
| Note also that there is no <b>Returns</b> clause for this function, which |
| should probably be corrected, just as should the second occurrence |
| of <i>"out."</i> in the text. |
| </p> |
| |
| <p> |
| I think the least invasive change to fix it would be something like |
| the following: |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.2.2.2.2 [facet.num.put.virtuals], just above paragraph 1, remove |
| the <tt>bool</tt> overload.</p> |
| |
| <p> |
| In 22.2.2.2.2 [facet.num.put.virtuals], p23, make the following changes |
| </p> |
| |
| <blockquote><p> |
| Replace <tt>put()</tt> with <tt>do_put()</tt> in the declaration |
| of the member function. |
| </p></blockquote> |
| |
| <blockquote><p> |
| Change the <b>Effects</b> clause to a <b>Returns</b> clause (to |
| avoid the requirement to call <tt>do_put(..., int)</tt> from <tt> |
| do_put (..., bool))</tt> |
| like so: |
| </p></blockquote> |
| |
| <blockquote><p> |
| 23 <b>Returns</b>: If <tt>(str.flags() & |
| ios_base::boolalpha) == 0</tt> then |
| <tt>do_put (out, str, fill, (long)val)</tt> |
| Otherwise the function obtains a string <tt>s</tt> as if by</p> |
| <pre> string_type s = |
| val ? use_facet<ctype<charT> >(loc).truename() |
| : use_facet<ctype<charT> >(loc).falsename(); |
| </pre> |
| <p>and then inserts each character <tt>c</tt> of s into out via |
| <tt>*out++ = c</tt> |
| and returns <tt>out</tt>.</p> |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p><p> |
| This fixes a couple of obvious typos, and also fixes what appears to |
| be a requirement of gratuitous inefficiency. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="360"></a>360. locale mandates inefficient implementation</h3> |
| <p><b>Section:</b> 22.1.1 [locale] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-03-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale">issues</a> in [locale].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 22.1.1, p7 (copied below) allows iostream formatters and extractors |
| to make assumptions about the values returned from facet members. |
| However, such assumptions are apparently not guaranteed to hold |
| in other cases (e.g., when the facet members are being called directly |
| rather than as a result of iostream calls, or between successive |
| calls to the same iostream functions with no interevening calls to |
| <tt>imbue()</tt>, or even when the facet member functions are called |
| from other member functions of other facets). This restriction |
| prevents locale from being implemented efficiently. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the first sentence in 22.1.1, p7 from</p> |
| <blockquote><p> |
| In successive calls to a locale facet member function during |
| a call to an iostream inserter or extractor or a streambuf member |
| function, the returned result shall be identical. [Note: This |
| implies that such results may safely be reused without calling |
| the locale facet member function again, and that member functions |
| of iostream classes cannot safely call <tt>imbue()</tt> |
| themselves, except as specified elsewhere. --end note] |
| </p></blockquote> |
| |
| <p>to</p> |
| |
| <blockquote><p> |
| In successive calls to a locale facet member function on a facet |
| object installed in the same locale, the returned result shall be |
| identical. ... |
| </p></blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>This change is reasonable becuase it clarifies the intent of this |
| part of the standard.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="362"></a>362. bind1st/bind2nd type safety</h3> |
| <p><b>Section:</b> D.8 [depr.lib.binders] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Andrew Demkin <b>Date:</b> 2002-04-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.lib.binders">issues</a> in [depr.lib.binders].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The definition of bind1st() (D.8 [depr.lib.binders]) can result in |
| the construction of an unsafe binding between incompatible pointer |
| types. For example, given a function whose first parameter type is |
| 'pointer to T', it's possible without error to bind an argument of |
| type 'pointer to U' when U does not derive from T: |
| </p> |
| <pre> foo(T*, int); |
| |
| struct T {}; |
| struct U {}; |
| |
| U u; |
| |
| int* p; |
| int* q; |
| |
| for_each(p, q, bind1st(ptr_fun(foo), &u)); // unsafe binding |
| </pre> |
| |
| <p> |
| The definition of bind1st() includes a functional-style conversion to |
| map its argument to the expected argument type of the bound function |
| (see below): |
| </p> |
| <pre> typename Operation::first_argument_type(x) |
| </pre> |
| |
| <p>A functional-style conversion (D.8 [depr.lib.binders]) is defined to |
| be |
| semantically equivalent to an explicit cast expression (D.8 |
| [depr.lib.binders]), which may (according to 5.4, paragraph 5) be |
| interpreted |
| as a reinterpret_cast, thus masking the error. |
| </p> |
| |
| <p>The problem and proposed change also apply to D.8 [depr.lib.binders].</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add this sentence to the end of D.8 [depr.lib.binders]/1: |
| "Binders <tt>bind1st</tt> and <tt>bind2nd</tt> are deprecated in |
| favor of <tt>std::tr1::bind</tt>."</p> |
| |
| <p>(Notes to editor: (1) when and if tr1::bind is incorporated into |
| the standard, "std::tr1::bind" should be changed to "std::bind". (2) |
| 20.5.6 should probably be moved to Annex D.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>There is no point in fixing bind1st and bind2nd. tr1::bind is a |
| superior solution. It solves this problem and others.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="363"></a>363. Missing exception specification in 27.4.2.1.1</h3> |
| <p><b>Section:</b> 27.4.2.1.1 [ios::failure] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown and Marc Paterno <b>Date:</b> 2002-05-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ios::failure">issues</a> in [ios::failure].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The destructor of ios_base::failure should have an empty throw |
| specification, because the destructor of its base class, exception, is |
| declared in this way. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the destructor to</p> |
| <pre> virtual ~failure() throw(); |
| </pre> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious glitch. This is almost editorial.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="364"></a>364. Inconsistent wording in 27.5.2.4.2</h3> |
| <p><b>Section:</b> 27.5.2.4.2 [streambuf.virt.buffer] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown, Marc Paterno <b>Date:</b> 2002-05-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#streambuf.virt.buffer">issues</a> in [streambuf.virt.buffer].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 27.5.2.4.2 [streambuf.virt.buffer] paragraph 1 is inconsistent with the Effects |
| clause for seekoff. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Make this paragraph, the Effects clause for setbuf, consistent in wording |
| with the Effects clause for seekoff in paragraph 3 by amending paragraph 1 |
| to indicate the purpose of setbuf: |
| </p> |
| |
| <p>Original text:</p> |
| |
| <blockquote><p> |
| 1 Effects: Performs an operation that is defined separately for each |
| class derived from basic_streambuf in this clause (27.7.1.3, 27.8.1.4). |
| </p></blockquote> |
| |
| <p>Proposed text:</p> |
| |
| <blockquote><p> |
| 1 Effects: Influences stream buffering in a way that is defined separately |
| for each class derived from basic_streambuf in this clause |
| (27.7.1.3, 27.8.1.4). |
| </p></blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG doesn't believe there is any normative difference between |
| the existing wording and what's in the proposed resolution, but the |
| change may make the intent clearer.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="365"></a>365. Lack of const-qualification in clause 27</h3> |
| <p><b>Section:</b> 27 [input.output] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown, Marc Paterno <b>Date:</b> 2002-05-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#input.output">issues</a> in [input.output].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Some stream and streambuf member functions are declared non-const, |
| even thought they appear only to report information rather than to |
| change an object's logical state. They should be declared const. See |
| document N1360 for details and rationale. |
| </p> |
| |
| <p>The list of member functions under discussion: <tt>in_avail</tt>, |
| <tt>showmanyc</tt>, <tt>tellg</tt>, <tt>tellp</tt>, <tt>is_open</tt>.</p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.5, 27.8.1.7, 27.8.1.8, 27.8.1.10, 27.8.1.11, and 27.8.1.13</p> |
| <p>Replace</p> |
| <pre> bool is_open(); |
| </pre> |
| <p>with</p> |
| <pre> bool is_open() const; |
| </pre> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Of the changes proposed in N1360, the only one that is safe is |
| changing the filestreams' is_open to const. The LWG believed that |
| this was NAD the first time it considered this issue (issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#73">73</a>), but now thinks otherwise. The corresponding streambuf |
| member function, after all,is already const.</p> |
| |
| <p>The other proposed changes are less safe, because some streambuf |
| functions that appear merely to report a value do actually perform |
| mutating operations. It's not even clear that they should be |
| considered "logically const", because streambuf has two interfaces, a |
| public one and a protected one. These functions may, and often do, |
| change the state as exposed by the protected interface, even if the |
| state exposed by the public interface is unchanged.</p> |
| |
| <p>Note that implementers can make this change in a binary compatible |
| way by providing both overloads; this would be a conforming extension.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="369"></a>369. io stream objects and static ctors</h3> |
| <p><b>Section:</b> 27.3 [iostream.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ruslan Abdikeev <b>Date:</b> 2002-07-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostream.objects">issues</a> in [iostream.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Is it safe to use standard iostream objects from constructors of |
| static objects? Are standard iostream objects constructed and are |
| their associations established at that time? |
| </p> |
| |
| <p>Surpisingly enough, Standard does NOT require that.</p> |
| |
| <p> |
| 27.3/2 [lib.iostream.objects] guarantees that standard iostream |
| objects are constructed and their associations are established before |
| the body of main() begins execution. It also refers to ios_base::Init |
| class as the panacea for constructors of static objects. |
| </p> |
| |
| <p> |
| However, there's nothing in 27.3 [lib.iostream.objects], |
| in 27.4.2 [lib.ios.base], and in 27.4.2.1.6 [lib.ios::Init], |
| that would require implementations to allow access to standard |
| iostream objects from constructors of static objects. |
| </p> |
| |
| <p>Details:</p> |
| |
| <p>Core text refers to some magic object ios_base::Init, which will |
| be discussed below:</p> |
| |
| <blockquote><p> |
| "The [standard iostream] objects are constructed, and their |
| associations are established at some time prior to or during |
| first time an object of class basic_ios<charT,traits>::Init |
| is constructed, and in any case before the body of main |
| begins execution." (27.3/2 [lib.iostream.objects]) |
| </p></blockquote> |
| |
| <p> |
| The first <i>non-normative</i> footnote encourages implementations |
| to initialize standard iostream objects earlier than required. |
| </p> |
| |
| <p>However, the second <i>non-normative</i> footnote makes an explicit |
| and unsupported claim:</p> |
| |
| <blockquote><p> |
| "Constructors and destructors for static objects can access these |
| [standard iostream] objects to read input from stdin or write output |
| to stdout or stderr." (27.3/2 footnote 265 [lib.iostream.objects]) |
| </p></blockquote> |
| |
| <p> |
| The only bit of magic is related to that ios_base::Init class. AFAIK, |
| the rationale behind ios_base::Init was to bring an instance of this |
| class to each translation unit which #included <iostream> or |
| related header. Such an inclusion would support the claim of footnote |
| quoted above, because in order to use some standard iostream object it |
| is necessary to #include <iostream>. |
| </p> |
| |
| <p> |
| However, while Standard explicitly describes ios_base::Init as |
| an appropriate class for doing the trick, I failed to found a |
| mention of an _instance_ of ios_base::Init in Standard. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add to 27.3 [iostream.objects], p2, immediately before the last sentence |
| of the paragraph, the following two sentences:</p> |
| |
| <blockquote><p> |
| If a translation unit includes <iostream>, or explicitly |
| constructs an ios_base::Init object, these stream objects shall |
| be constructed before dynamic initialization of non-local |
| objects defined later in that translation unit, and these stream |
| objects shall be destroyed after the destruction of dynamically |
| initialized non-local objects defined later in that translation unit. |
| </p></blockquote> |
| |
| <p><i>[Lillehammer: Matt provided wording.]</i></p> |
| |
| <p><i>[Mont Tremblant: Matt provided revised wording.]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The original proposed resolution unconditionally required |
| implementations to define an ios_base::Init object of some |
| implementation-defined name in the header <iostream>. That's an |
| overspecification. First, defining the object may be unnecessary |
| and even detrimental to performance if an implementation can |
| guarantee that the 8 standard iostream objects will be initialized |
| before any other user-defined object in a program. Second, there |
| is no need to require implementations to document the name of the |
| object.</p> |
| |
| <p> |
| The new proposed resolution gives users guidance on what they need to |
| do to ensure that stream objects are constructed during startup.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="370"></a>370. Minor error in basic_istream::get</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ray Lischner <b>Date:</b> 2002-07-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Defect report for description of basic_istream::get (section |
| 27.6.1.3 [istream.unformatted]), paragraph 15. The description for the |
| get function |
| with the following signature:</p> |
| |
| <pre> basic_istream<charT,traits>& get(basic_streambuf<char_type,traits>& |
| sb); |
| </pre> |
| |
| <p>is incorrect. It reads</p> |
| |
| <blockquote><p> |
| Effects: Calls get(s,n,widen('\n')) |
| </p></blockquote> |
| |
| <p>which I believe should be:</p> |
| |
| <blockquote><p> |
| Effects: Calls get(sb,widen('\n')) |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the <b>Effects</b> paragraph to:</p> |
| <blockquote><p> |
| Effects: Calls get(sb,this->widen('\n')) |
| </p></blockquote> |
| |
| <p><i>[Pre-Oxford: Minor correction from Howard: replaced 'widen' |
| with 'this->widen'.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p><p>Fixes an obvious typo.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="371"></a>371. Stability of multiset and multimap member functions</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Frank Compagner <b>Date:</b> 2002-07-20</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The requirements for multiset and multimap containers (23.1 |
| [lib.containers.requirements], 23.1.2 [lib.associative.reqmnts], |
| 23.3.2 [lib.multimap] and 23.3.4 [lib.multiset]) make no mention of |
| the stability of the required (mutating) member functions. It appears |
| the standard allows these functions to reorder equivalent elements of |
| the container at will, yet the pervasive red-black tree implementation |
| appears to provide stable behaviour. |
| </p> |
| |
| <p>This is of most concern when considering the behaviour of erase(). |
| A stability requirement would guarantee the correct working of the |
| following 'idiom' that removes elements based on a certain predicate |
| function. |
| </p> |
| |
| <pre> multimap<int, int> m; |
| multimap<int, int>::iterator i = m.begin(); |
| while (i != m.end()) { |
| if (pred(i)) |
| m.erase (i++); |
| else |
| ++i; |
| } |
| </pre> |
| |
| <p> |
| Although clause 23.1.2/8 guarantees that i remains a valid iterator |
| througout this loop, absence of the stability requirement could |
| potentially result in elements being skipped. This would make |
| this code incorrect, and, furthermore, means that there is no way |
| of erasing these elements without iterating first over the entire |
| container, and second over the elements to be erased. This would |
| be unfortunate, and have a negative impact on both performance and |
| code simplicity. |
| </p> |
| |
| <p> |
| If the stability requirement is intended, it should be made explicit |
| (probably through an extra paragraph in clause 23.1.2). |
| </p> |
| <p> |
| If it turns out stability cannot be guaranteed, i'd argue that a |
| remark or footnote is called for (also somewhere in clause 23.1.2) to |
| warn against relying on stable behaviour (as demonstrated by the code |
| above). If most implementations will display stable behaviour, any |
| problems emerging on an implementation without stable behaviour will |
| be hard to track down by users. This would also make the need for an |
| erase_if() member function that much greater. |
| </p> |
| |
| <p>This issue is somewhat related to LWG issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following to the end of 23.1.4 [associative.reqmts] paragraph 4: |
| "For <tt>multiset</tt> and <tt>multimap</tt>, <tt>insert</tt>and <tt>erase</tt> |
| are <i>stable</i>: they preserve the relative ordering of equivalent |
| elements.</p> |
| |
| <p><i>[Lillehammer: Matt provided wording]</i></p> |
| |
| <p><i>[Joe Gottman points out that the provided wording does not address |
| multimap and multiset. N1780 also addresses this issue and suggests |
| wording.]</i></p> |
| |
| |
| <p><i>[Mont Tremblant: Changed set and map to multiset and multimap.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG agrees that this guarantee is necessary for common user |
| idioms to work, and that all existing implementations provide this |
| property. Note that this resolution guarantees stability for |
| multimap and multiset, not for all associative containers in |
| general.</p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="373"></a>373. Are basic_istream and basic_ostream to use (exceptions()&badbit) != 0 ?</h3> |
| <p><b>Section:</b> 27.6.1.2.1 [istream.formatted.reqmts], 27.6.2.6.1 [ostream.formatted.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Keith Baker <b>Date:</b> 2002-07-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.formatted.reqmts">issues</a> in [istream.formatted.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| In 27.6.1.2.1 [istream.formatted.reqmts] and 27.6.2.6.1 [ostream.formatted.reqmts] |
| (exception()&badbit) != 0 is used in testing for rethrow, yet |
| exception() is the constructor to class std::exception in 18.6.1 [type.info] that has no return type. Should member function |
| exceptions() found in 27.4.4 [ios] be used instead? |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.1.2.1 [istream.formatted.reqmts] and 27.6.2.6.1 [ostream.formatted.reqmts], change |
| "(exception()&badbit) != 0" to "(exceptions()&badbit) != 0". |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Fixes an obvious typo.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="375"></a>375. basic_ios should be ios_base in 27.7.1.3</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ray Lischner <b>Date:</b> 2002-08-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In Section 27.7.1.4 [stringbuf.virtuals]: Table 90, Table 91, and paragraph |
| 14 all contain references to "basic_ios::" which should be |
| "ios_base::". |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change all references to "basic_ios" in Table 90, Table 91, and |
| paragraph 14 to "ios_base". |
| </p> |
| |
| |
| <p><b>Rationale:</b></p><p>Fixes an obvious typo.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="376"></a>376. basic_streambuf semantics</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ray Lischner <b>Date:</b> 2002-08-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In Section 27.7.1.4 [stringbuf.virtuals], Table 90, the implication is that |
| the four conditions should be mutually exclusive, but they are not. |
| The first two cases, as written, are subcases of the third.</p> |
| |
| <p> |
| As written, it is unclear what should be the result if cases 1 and 2 |
| are both true, but case 3 is false. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Rewrite these conditions as:</p> |
| <blockquote> |
| <p> |
| (which & (ios_base::in|ios_base::out)) == ios_base::in |
| </p> |
| |
| <p> |
| (which & (ios_base::in|ios_base::out)) == ios_base::out |
| </p> |
| |
| <p> |
| (which & (ios_base::in|ios_base::out)) == |
| (ios_base::in|ios_base::out) |
| and way == either ios_base::beg or ios_base::end |
| </p> |
| |
| <p>Otherwise</p> |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>It's clear what we wanted to say, we just failed to say it. This |
| fixes it.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="379"></a>379. nonsensical ctype::do_widen() requirement</h3> |
| <p><b>Section:</b> 22.2.1.1.2 [locale.ctype.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-09-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.ctype.virtuals">issues</a> in [locale.ctype.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The last sentence in 22.2.1.1.2, p11 below doesn't seem to make sense. |
| </p> |
| <pre> charT do_widen (char c) const; |
| |
| -11- Effects: Applies the simplest reasonable transformation from |
| a char value or sequence of char values to the corresponding |
| charT value or values. The only characters for which unique |
| transformations are required are those in the basic source |
| character set (2.2). For any named ctype category with a |
| ctype<charT> facet ctw and valid ctype_base::mask value |
| M (is(M, c) || !ctw.is(M, do_widen(c))) is true. |
| </pre> |
| <p> |
| Shouldn't the last sentence instead read |
| </p> |
| <pre> For any named ctype category with a ctype<char> facet ctc |
| and valid ctype_base::mask value M |
| (ctc.is(M, c) || !is(M, do_widen(c))) is true. |
| </pre> |
| <p> |
| I.e., if the narrow character c is not a member of a class of |
| characters then neither is the widened form of c. (To paraphrase |
| footnote 224.) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace the last sentence of 22.2.1.1.2 [locale.ctype.virtuals], p11 with the |
| following text: |
| </p> |
| <pre> For any named ctype category with a ctype<char> facet ctc |
| and valid ctype_base::mask value M, |
| (ctc.is(M, c) || !is(M, do_widen(c))) is true. |
| </pre> |
| |
| <p><i>[Kona: Minor edit. Added a comma after the <i>M</i> for clarity.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes this is just a typo, and that this is the correct fix.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="380"></a>380. typos in codecvt tables 53 and 54</h3> |
| <p><b>Section:</b> 22.2.1.5 [locale.codecvt.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-09-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt.byname">issues</a> in [locale.codecvt.byname].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Tables 53 and 54 in 22.2.1.5 [locale.codecvt.byname] are both titled "convert |
| result values," when surely "do_in/do_out result values" must have |
| been intended for Table 53 and "do_unshift result values" for Table |
| 54. |
| </p> |
| <p> |
| Table 54, row 3 says that the meaning of partial is "more characters |
| needed to be supplied to complete termination." The function is not |
| supplied any characters, it is given a buffer which it fills with |
| characters or, more precisely, destination elements (i.e., an escape |
| sequence). So partial means that space for more than (to_limit - to) |
| destination elements was needed to terminate a sequence given the |
| value of state. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the title of Table 53 to "do_in/do_out result values" and |
| the title of Table 54 to "do_unshift result values." |
| </p> |
| <p> |
| Change the text in Table 54, row 3 (the <b>partial</b> row), under the |
| heading Meaning, to "space for more than (to_limit - to) destination |
| elements was needed to terminate a sequence given the value of state." |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="381"></a>381. detection of invalid mbstate_t in codecvt</h3> |
| <p><b>Section:</b> 22.2.1.5 [locale.codecvt.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2002-09-06</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt.byname">issues</a> in [locale.codecvt.byname].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| All but one codecvt member functions that take a state_type argument |
| list as one of their preconditions that the state_type argument have |
| a valid value. However, according to 22.2.1.5.2, p6, |
| codecvt::do_unshift() is the only codecvt member that is supposed to |
| return error if the state_type object is invalid. |
| </p> |
| |
| <p> |
| It seems to me that the treatment of state_type by all codecvt member |
| functions should be the same and the current requirements should be |
| changed. Since the detection of invalid state_type values may be |
| difficult in general or computationally expensive in some specific |
| cases, I propose the following: |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new paragraph before 22.2.1.5.2, p5, and after the function |
| declaration below |
| </p> |
| <pre> result do_unshift(stateT& state, |
| externT* to, externT* to_limit, externT*& to_next) const; |
| </pre> |
| <p> |
| as follows: |
| </p> |
| <pre> Requires: (to <= to_end) well defined and true; state initialized, |
| if at the beginning of a sequence, or else equal to the result of |
| converting the preceding characters in the sequence. |
| </pre> |
| <p> |
| and change the text in Table 54, row 4, the <b>error</b> row, under |
| the heading Meaning, from |
| </p> |
| <pre> state has invalid value |
| </pre> |
| <p> |
| to |
| </p> |
| <pre> an unspecified error has occurred |
| </pre> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The intent is that implementations should not be required to detect |
| invalid state values; such a requirement appears nowhere else. An |
| invalid state value is a precondition violation, <i>i.e.</i> undefined |
| behavior. Implementations that do choose to detect invalid state |
| values, or that choose to detect any other kind of error, may return |
| <b>error</b> as an indication.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="383"></a>383. Bidirectional iterator assertion typo</h3> |
| <p><b>Section:</b> 24.1.4 [bidirectional.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> ysapir (submitted via comp.std.c++) <b>Date:</b> 2002-10-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#bidirectional.iterators">issues</a> in [bidirectional.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Following a discussion on the boost list regarding end iterators and |
| the possibility of performing operator--() on them, it seems to me |
| that there is a typo in the standard. This typo has nothing to do |
| with that discussion. |
| </p> |
| |
| <p> |
| I have checked this newsgroup, as well as attempted a search of the |
| Active/Defect/Closed Issues List on the site for the words "s is |
| derefer" so I believe this has not been proposed before. Furthermore, |
| the "Lists by Index" mentions only DR <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a> on section |
| 24.1.4, and DR <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a> is not related to this issue. |
| </p> |
| |
| <p> |
| The standard makes the following assertion on bidirectional iterators, |
| in section 24.1.4 [lib.bidirectional.iterators], Table 75: |
| </p> |
| |
| <pre> operational assertion/note |
| expression return type semantics pre/post-condition |
| |
| --r X& pre: there exists s such |
| that r == ++s. |
| post: s is dereferenceable. |
| --(++r) == r. |
| --r == --s implies r == s. |
| &r == &--r. |
| </pre> |
| |
| <p> |
| (See <a href="http://aspn.activestate.com/ASPN/Mail/Message/boost/1395763">http://aspn.activestate.com/ASPN/Mail/Message/boost/1395763</a>.) |
| </p> |
| |
| <p> |
| In particular, "s is dereferenceable" seems to be in error. It seems |
| that the intention was to say "r is dereferenceable". |
| </p> |
| |
| <p> |
| If it were to say "r is dereferenceable" it would |
| make perfect sense. Since s must be dereferenceable prior to |
| operator++, then the natural result of operator-- (to undo operator++) |
| would be to make r dereferenceable. Furthermore, without other |
| assertions, and basing only on precondition and postconditions, we |
| could not otherwise know this. So it is also interesting information. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the guarantee to "postcondition: r is dereferenceable." |
| </p> |
| |
| |
| <p><b>Rationale:</b></p><p>Fixes an obvious typo</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="384"></a>384. equal_range has unimplementable runtime complexity</h3> |
| <p><b>Section:</b> 25.3.3.3 [equal.range] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Hans Bos <b>Date:</b> 2002-10-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#equal.range">issues</a> in [equal.range].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 25.3.3.3 [equal.range] |
| states that at most 2 * log(last - first) + 1 |
| comparisons are allowed for equal_range. |
| </p> |
| |
| <p>It is not possible to implement equal_range with these constraints.</p> |
| |
| <p>In a range of one element as in:</p> |
| <pre> int x = 1; |
| equal_range(&x, &x + 1, 1) |
| </pre> |
| |
| <p>it is easy to see that at least 2 comparison operations are needed.</p> |
| |
| <p>For this case at most 2 * log(1) + 1 = 1 comparison is allowed.</p> |
| |
| <p>I have checked a few libraries and they all use the same (nonconforming) |
| algorithm for equal_range that has a complexity of</p> |
| <pre> 2* log(distance(first, last)) + 2. |
| </pre> |
| <p>I guess this is the algorithm that the standard assumes for equal_range.</p> |
| |
| <p> |
| It is easy to see that 2 * log(distance) + 2 comparisons are enough |
| since equal range can be implemented with lower_bound and upper_bound |
| (both log(distance) + 1). |
| </p> |
| |
| <p> |
| I think it is better to require something like 2log(distance) + O(1) (or |
| even logarithmic as multiset::equal_range). |
| Then an implementation has more room to optimize for certain cases (e.g. |
| have log(distance) characteristics when at most match is found in the range |
| but 2log(distance) + 4 for the worst case). |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25.3.3.1 [lower.bound]/4, change <tt>log(last - first) + 1</tt> |
| to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p>In 25.3.3.2 [upper.bound]/4, change <tt>log(last - first) + 1</tt> |
| to <tt>log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p>In 25.3.3.3 [equal.range]/4, change <tt>2*log(last - first) + 1</tt> |
| to <tt>2*log<sub>2</sub>(last - first) + <i>O</i>(1)</tt>.</p> |
| |
| <p><i>[Matt provided wording]</i></p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered just saying <i>O</i>(log n) for all three, but |
| decided that threw away too much valuable information. The fact |
| that lower_bound is twice as fast as equal_range is important. |
| However, it's better to allow an arbitrary additive constant than to |
| specify an exact count. An exact count would have to |
| involve <tt>floor</tt> or <tt>ceil</tt>. It would be too easy to |
| get this wrong, and don't provide any substantial value for users.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="386"></a>386. Reverse iterator's operator[] has impossible return type</h3> |
| <p><b>Section:</b> 24.4.1.3.11 [reverse.iter.op-=] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2002-10-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In 24.4.1.3.11 [reverse.iter.op-=], <tt>reverse_iterator<>::operator[]</tt> |
| is specified as having a return type of <tt>reverse_iterator::reference</tt>, |
| which is the same as <tt>iterator_traits<Iterator>::reference</tt>. |
| (Where <tt>Iterator</tt> is the underlying iterator type.)</p> |
| |
| <p>The trouble is that <tt>Iterator</tt>'s own operator[] doesn't |
| necessarily have a return type |
| of <tt>iterator_traits<Iterator>::reference</tt>. Its |
| return type is merely required to be convertible |
| to <tt>Iterator</tt>'s value type. The return type specified for |
| reverse_iterator's operator[] would thus appear to be impossible.</p> |
| |
| <p>With the resolution of issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#299">299</a>, the type of |
| <tt>a[n]</tt> will continue to be required (for random access |
| iterators) to be convertible to the value type, and also <tt>a[n] = |
| t</tt> will be a valid expression. Implementations of |
| <tt>reverse_iterator</tt> will likely need to return a proxy from |
| <tt>operator[]</tt> to meet these requirements. As mentioned in the |
| comment from Dave Abrahams, the simplest way to specify that |
| <tt>reverse_iterator</tt> meet this requirement to just mandate |
| it and leave the return type of <tt>operator[]</tt> unspecified.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 24.4.1.2 [reverse.iter.requirements] change:</p> |
| |
| <blockquote> |
| <pre>reference operator[](difference_type n) const; |
| </pre> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <pre><b><i>unspecified</i></b> operator[](difference_type n) const; // see 24.1.5 [random.access.iterators] |
| </pre> |
| </blockquote> |
| |
| |
| |
| |
| <p><i>[ |
| Comments from Dave Abrahams: IMO we should resolve 386 by just saying |
| that the return type of reverse_iterator's operator[] is |
| unspecified, allowing the random access iterator requirements to |
| impose an appropriate return type. If we accept 299's proposed |
| resolution (and I think we should), the return type will be |
| readable and writable, which is about as good as we can do. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="389"></a>389. Const overload of valarray::operator[] returns by value</h3> |
| <p><b>Section:</b> 26.5.2.3 [valarray.access] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 2002-11-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#valarray.access">issues</a> in [valarray.access].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#77">77</a></p> |
| <p><b>Discussion:</b></p> |
| <p>Consider the following program:</p> |
| <pre> #include <iostream> |
| #include <ostream> |
| #include <vector> |
| #include <valarray> |
| #include <algorithm> |
| #include <iterator> |
| template<typename Array> |
| void print(const Array& a) |
| { |
| using namespace std; |
| typedef typename Array::value_type T; |
| copy(&a[0], &a[0] + a.size(), |
| ostream_iterator<T>(std::cout, " ")); |
| } |
| template<typename T, unsigned N> |
| unsigned size(T(&)[N]) { return N; } |
| int main() |
| { |
| double array[] = { 0.89, 9.3, 7, 6.23 }; |
| std::vector<double> v(array, array + size(array)); |
| std::valarray<double> w(array, size(array)); |
| print(v); // #1 |
| std::cout << std::endl; |
| print(w); // #2 |
| std::cout << std::endl; |
| } |
| </pre> |
| |
| <p>While the call numbered #1 succeeds, the call numbered #2 fails |
| because the const version of the member function |
| valarray<T>::operator[](size_t) returns a value instead of a |
| const-reference. That seems to be so for no apparent reason, no |
| benefit. Not only does that defeats users' expectation but it also |
| does hinder existing software (written either in C or Fortran) |
| integration within programs written in C++. There is no reason why |
| subscripting an expression of type valarray<T> that is const-qualified |
| should not return a const T&.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the class synopsis in 26.5.2 [template.valarray], and in |
| 26.5.2.3 [valarray.access] just above paragraph 1, change</p> |
| <pre> T operator[](size_t const); |
| </pre> |
| <p>to</p> |
| <pre> const T& operator[](size_t const); |
| </pre> |
| |
| <p><i>[Kona: fixed a minor typo: put semicolon at the end of the line |
| wehre it belongs.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Return by value seems to serve no purpose. Valaray was explicitly |
| designed to have a specified layout so that it could easily be |
| integrated with libraries in other languages, and return by value |
| defeats that purpose. It is believed that this change will have no |
| impact on allowable optimizations.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="391"></a>391. non-member functions specified as const</h3> |
| <p><b>Section:</b> 22.1.3.2 [conversions] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> James Kanze <b>Date:</b> 2002-12-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The specifications of toupper and tolower both specify the functions as |
| const, althought they are not member functions, and are not specified as |
| const in the header file synopsis in section 22.1 [locales]. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 22.1.3.2 [conversions], remove <tt>const</tt> from the function |
| declarations of std::toupper and std::tolower</p> |
| |
| |
| <p><b>Rationale:</b></p><p>Fixes an obvious typo</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="395"></a>395. inconsistencies in the definitions of rand() and random_shuffle()</h3> |
| <p><b>Section:</b> 26.7 [c.math] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> James Kanze <b>Date:</b> 2003-01-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#c.math">issues</a> in [c.math].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 26.7 [c.math], the C++ standard refers to the C standard for the |
| definition of rand(); in the C standard, it is written that "The |
| implementation shall behave as if no library function calls the rand |
| function." |
| </p> |
| |
| <p> |
| In 25.2.12 [alg.random.shuffle], there is no specification as to |
| how the two parameter version of the function generates its random |
| value. I believe that all current implementations in fact call rand() |
| (in contradiction with the requirement avove); if an implementation does |
| not call rand(), there is the question of how whatever random generator |
| it does use is seeded. Something is missing. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In [lib.c.math], add a paragraph specifying that the C definition of |
| rand shal be modified to say that "Unless otherwise specified, the |
| implementation shall behave as if no library function calls the rand |
| function." |
| </p> |
| |
| <p> |
| In [lib.alg.random.shuffle], add a sentence to the effect that "In |
| the two argument form of the function, the underlying source of |
| random numbers is implementation defined. [Note: in particular, an |
| implementation is permitted to use <tt>rand</tt>.] |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The original proposed resolution proposed requiring the |
| two-argument from of <tt>random_shuffle</tt> to |
| use <tt>rand</tt>. We don't want to do that, because some existing |
| implementations already use something else: gcc |
| uses <tt>lrand48</tt>, for example. Using <tt>rand</tt> presents a |
| problem if the number of elements in the sequence is greater than |
| RAND_MAX.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="400"></a>400. redundant type cast in lib.allocator.members</h3> |
| <p><b>Section:</b> 20.7.5.1 [allocator.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Markus Mauhart <b>Date:</b> 2003-02-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.members">issues</a> in [allocator.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 20.7.5.1 [allocator.members] allocator members, contains |
| the following 3 lines: |
| </p> |
| |
| <pre> 12 Returns: new((void *) p) T( val) |
| void destroy(pointer p); |
| 13 Returns: ((T*) p)->~T() |
| </pre> |
| |
| <p> |
| The type cast "(T*) p" in the last line is redundant cause |
| we know that std::allocator<T>::pointer is a typedef for T*. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace "((T*) p)" with "p". |
| </p> |
| |
| |
| <p><b>Rationale:</b></p><p>Just a typo, this is really editorial.</p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="401"></a>401. incorrect type casts in table 32 in lib.allocator.requirements</h3> |
| <p><b>Section:</b> 20.1.2 [allocator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Markus Mauhart <b>Date:</b> 2003-02-27</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I think that in par2 of [default.con.req] the last two |
| lines of table 32 contain two incorrect type casts. The lines are ... |
| </p> |
| |
| <pre> a.construct(p,t) Effect: new((void*)p) T(t) |
| a.destroy(p) Effect: ((T*)p)?->~T() |
| </pre> |
| |
| <p> |
| .... with the prerequisits coming from the preceding two paragraphs, especially |
| from table 31: |
| </p> |
| |
| <pre> alloc<T> a ;// an allocator for T |
| alloc<T>::pointer p ;// random access iterator |
| // (may be different from T*) |
| alloc<T>::reference r = *p;// T& |
| T const& t ; |
| </pre> |
| |
| <p> |
| For that two type casts ("(void*)p" and "(T*)p") to be well-formed |
| this would require then conversions to T* and void* for all |
| alloc<T>::pointer, so it would implicitely introduce extra |
| requirements for alloc<T>::pointer, additionally to the only |
| current requirement (being a random access iterator). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Accept proposed wording from |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2436.pdf">N2436</a> part 1. |
| </p> |
| |
| <p> |
| Note: Actually I would prefer to replace "((T*)p)?->dtor_name" with |
| "p?->dtor_name", but AFAICS this is not possible cause of an omission |
| in 13.5.6 [over.ref] (for which I have filed another DR on 29.11.2002). |
| </p> |
| |
| <p><i>[Kona: The LWG thinks this is somewhere on the border between |
| Open and NAD. The intend is clear: <tt>construct</tt> constructs an |
| object at the location <i>p</i>. It's reading too much into the |
| description to think that literally calling <tt>new</tt> is |
| required. Tweaking this description is low priority until we can do |
| a thorough review of allocators, and, in particular, allocators with |
| non-default pointer types.]</i></p> |
| |
| |
| <p><i>[ |
| Batavia: Proposed resolution changed to less code and more description. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| post Oxford: This would be rendered NAD Editorial by acceptance of |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html">N2257</a>. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2387 for this issue which |
| was subsequently split out into a separate paper N2436 for the purposes of voting. |
| The resolution in N2436 addresses this issue. The LWG voted to accelerate this |
| issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="402"></a>402. wrong new expression in [some_]allocator::construct</h3> |
| <p><b>Section:</b> 20.1.2 [allocator.requirements], 20.7.5.1 [allocator.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Markus Mauhart <b>Date:</b> 2003-02-27</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#allocator.requirements">active issues</a> in [allocator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.requirements">issues</a> in [allocator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| This applies to the new expression that is contained in both par12 of |
| 20.7.5.1 [allocator.members] and in par2 (table 32) of [default.con.req]. |
| I think this new expression is wrong, involving unintended side |
| effects. |
| </p> |
| |
| |
| <p>20.7.5.1 [allocator.members] contains the following 3 lines:</p> |
| |
| <pre> 11 Returns: the largest value N for which the call allocate(N,0) might succeed. |
| void construct(pointer p, const_reference val); |
| 12 Returns: new((void *) p) T( val) |
| </pre> |
| |
| |
| <p> [default.con.req] in table 32 has the following line:</p> |
| <pre> a.construct(p,t) Effect: new((void*)p) T(t) |
| </pre> |
| |
| <p> |
| .... with the prerequisits coming from the preceding two paragraphs, |
| especially from table 31: |
| </p> |
| |
| <pre> alloc<T> a ;// an allocator for T |
| alloc<T>::pointer p ;// random access iterator |
| // (may be different from T*) |
| alloc<T>::reference r = *p;// T& |
| T const& t ; |
| </pre> |
| |
| <p> |
| Cause of using "new" but not "::new", any existing "T::operator new" |
| function will hide the global placement new function. When there is no |
| "T::operator new" with adequate signature, |
| every_alloc<T>::construct(..) is ill-formed, and most |
| std::container<T,every_alloc<T>> use it; a workaround |
| would be adding placement new and delete functions with adequate |
| signature and semantic to class T, but class T might come from another |
| party. Maybe even worse is the case when T has placement new and |
| delete functions with adequate signature but with "unknown" semantic: |
| I dont like to speculate about it, but whoever implements |
| any_container<T,any_alloc> and wants to use construct(..) |
| probably must think about it. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Replace "new" with "::new" in both cases. |
| </p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="403"></a>403. basic_string::swap should not throw exceptions</h3> |
| <p><b>Section:</b> 21.3.6.8 [string::swap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2003-03-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::swap">issues</a> in [string::swap].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| std::basic_string, 21.3 [basic.string] paragraph 2 says that |
| basic_string "conforms to the requirements of a Sequence, as specified |
| in (23.1.1)." The sequence requirements specified in (23.1.1) to not |
| include any prohibition on swap members throwing exceptions. |
| </p> |
| |
| <p> |
| Section 23.1 [container.requirements] paragraph 10 does limit conditions under |
| which exceptions may be thrown, but applies only to "all container |
| types defined in this clause" and so excludes basic_string::swap |
| because it is defined elsewhere. |
| </p> |
| |
| <p> |
| Eric Niebler points out that 21.3 [basic.string] paragraph 5 explicitly |
| permits basic_string::swap to invalidates iterators, which is |
| disallowed by 23.1 [container.requirements] paragraph 10. Thus the standard would |
| be contradictory if it were read or extended to read as having |
| basic_string meet 23.1 [container.requirements] paragraph 10 requirements. |
| </p> |
| |
| <p> |
| Yet several LWG members have expressed the belief that the original |
| intent was that basic_string::swap should not throw exceptions as |
| specified by 23.1 [container.requirements] paragraph 10, and that the standard is |
| unclear on this issue. The complexity of basic_string::swap is |
| specified as "constant time", indicating the intent was to avoid |
| copying (which could cause a bad_alloc or other exception). An |
| important use of swap is to ensure that exceptions are not thrown in |
| exception-safe code. |
| </p> |
| |
| <p> |
| Note: There remains long standing concern over whether or not it is |
| possible to reasonably meet the 23.1 [container.requirements] paragraph 10 swap |
| requirements when allocators are unequal. The specification of |
| basic_string::swap exception requirements is in no way intended to |
| address, prejudice, or otherwise impact that concern. |
| </p> |
| |
| |
| |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 21.3.6.8 [string::swap], add a throws clause: |
| </p> |
| |
| <p> |
| Throws: Shall not throw exceptions. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="404"></a>404. May a replacement allocation function be declared inline?</h3> |
| <p><b>Section:</b> 17.4.3.5 [replacement.functions], 18.5.1 [new.delete] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2003-04-24</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The eight basic dynamic memory allocation functions (single-object |
| and array versions of ::operator new and ::operator delete, in the |
| ordinary and nothrow forms) are replaceable. A C++ program may |
| provide an alternative definition for any of them, which will be used |
| in preference to the implementation's definition. |
| </p> |
| |
| <p> |
| Three different parts of the standard mention requirements on |
| replacement functions: 17.4.3.5 [replacement.functions], 18.5.1.1 [new.delete.single] |
| and 18.5.1.2 [new.delete.array], and 3.7.2 [basic.stc.auto]. |
| </p> |
| |
| <p>None of these three places say whether a replacement function may |
| be declared inline. 18.5.1.1 [new.delete.single] paragraph 2 specifies a |
| signature for the replacement function, but that's not enough: |
| the <tt>inline</tt> specifier is not part of a function's signature. |
| One might also reason from 7.1.2 [dcl.fct.spec] paragraph 2, which |
| requires that "an inline function shall be defined in every |
| translation unit in which it is used," but this may not be quite |
| specific enough either. We should either explicitly allow or |
| explicitly forbid inline replacement memory allocation |
| functions.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new sentence to the end of 17.4.3.5 [replacement.functions] paragraph 3: |
| "The program's definitions shall not be specified as <tt>inline</tt>. |
| No diagnostic is required." |
| </p> |
| |
| <p><i>[Kona: added "no diagnostic is required"]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| The fact that <tt>inline</tt> isn't mentioned appears to have been |
| nothing more than an oversight. Existing implementations do not |
| permit inline functions as replacement memory allocation functions. |
| Providing this functionality would be difficult in some cases, and is |
| believed to be of limited value. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="405"></a>405. qsort and POD</h3> |
| <p><b>Section:</b> 25.4 [alg.c.library] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ray Lischner <b>Date:</b> 2003-04-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.c.library">issues</a> in [alg.c.library].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 25.4 [alg.c.library] describes bsearch and qsort, from the C |
| standard library. Paragraph 4 does not list any restrictions on qsort, |
| but it should limit the base parameter to point to POD. Presumably, |
| qsort sorts the array by copying bytes, which requires POD. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 25.4 [alg.c.library] paragraph 4, just after the declarations and |
| before the nonnormative note, add these words: "both of which have the |
| same behavior as the original declaration. The behavior is undefined |
| unless the objects in the array pointed to by <i>base</i> are of POD |
| type." |
| </p> |
| |
| <p><i>[Something along these lines is clearly necessary. Matt |
| provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="406"></a>406. vector::insert(s) exception safety</h3> |
| <p><b>Section:</b> 23.2.6.4 [vector.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2003-04-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.modifiers">issues</a> in [vector.modifiers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| There is a possible defect in the standard: the standard text was |
| never intended to prevent arbitrary ForwardIterators, whose operations |
| may throw exceptions, from being passed, and it also wasn't intended |
| to require a temporary buffer in the case where ForwardIterators were |
| passed (and I think most implementations don't use one). As is, the |
| standard appears to impose requirements that aren't met by any |
| existing implementation. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace 23.2.6.4 [vector.modifiers] paragraph 1 with:</p> |
| <blockquote><p> |
| 1- Notes: Causes reallocation if the new size is greater than the |
| old capacity. If no reallocation happens, all the iterators and |
| references before the insertion point remain valid. If an exception |
| is thrown other than by the copy constructor or assignment operator |
| of T or by any InputIterator operation there are no effects. |
| </p></blockquote> |
| |
| <p><i>[We probably need to say something similar for deque.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="407"></a>407. Can singular iterators be destroyed?</h3> |
| <p><b>Section:</b> 24.1 [iterator.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 2003-06-03</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#iterator.requirements">active issues</a> in [iterator.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iterator.requirements">issues</a> in [iterator.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Clause 24.1 [iterator.requirements], paragraph 5, says that the only expression |
| that is defined for a singular iterator is "an assignment of a |
| non-singular value to an iterator that holds a singular value". This |
| means that destroying a singular iterator (e.g. letting an automatic |
| variable go out of scope) is technically undefined behavior. This |
| seems overly strict, and probably unintentional. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the sentence in question to "... the only exceptions are |
| destroying an iterator that holds a singular value, or the assignment |
| of a non-singular value to an iterator that holds a singular value." |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="409"></a>409. Closing an fstream should clear error state</h3> |
| <p><b>Section:</b> 27.8.1.9 [ifstream.members], 27.8.1.13 [ofstream.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Nathan Myers <b>Date:</b> 2003-06-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ifstream.members">issues</a> in [ifstream.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| A strict reading of 27.8.1 [fstreams] shows that opening or |
| closing a basic_[io]fstream does not affect the error bits. This |
| means, for example, that if you read through a file up to EOF, and |
| then close the stream and reopen it at the beginning of the file, |
| the EOF bit in the stream's error state is still set. This is |
| counterintuitive. |
| </p> |
| <p> |
| The LWG considered this issue once before, as issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#22">22</a>, |
| and put in a footnote to clarify that the strict reading was indeed |
| correct. We did that because we believed the standard was |
| unambiguous and consistent, and that we should not make architectural |
| changes in a TC. Now that we're working on a new revision of the |
| language, those considerations no longer apply. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Change 27.8.1.9 [ifstream.members], para. 3 from:</p> |
| |
| <blockquote><p> |
| Calls rdbuf()->open(s,mode|in). If that function returns a null |
| pointer, calls setstate(failbit) (which may throw ios_base::failure |
| [Footnote: (lib.iostate.flags)]. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p>Calls rdbuf()->open(s,mode|in). If that function |
| returns a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)), else calls clear(). |
| </p></blockquote> |
| |
| <p>Change 27.8.1.13 [ofstream.members], para. 3 from:</p> |
| |
| <blockquote><p>Calls rdbuf()->open(s,mode|out). If that function |
| returns a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)). |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p>Calls rdbuf()->open(s,mode|out). If that function |
| returns a null pointer, calls setstate(failbit) (which may throw |
| ios_base::failure [Footnote: (lib.iostate.flags)), else calls clear(). |
| </p></blockquote> |
| |
| <p>Change 27.8.1.17 [fstream.members], para. 3 from:</p> |
| |
| <blockquote><p>Calls rdbuf()->open(s,mode), If that function returns |
| a null pointer, calls setstate(failbit), (which may throw |
| ios_base::failure). (lib.iostate.flags) ) |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p>Calls rdbuf()->open(s,mode), If that function returns |
| a null pointer, calls setstate(failbit), (which may throw |
| ios_base::failure). (lib.iostate.flags) ), else calls clear(). |
| </p></blockquote> |
| |
| |
| |
| <p><i>[Kona: the LWG agrees this is a good idea. Post-Kona: Bill |
| provided wording. He suggests having open, not close, clear the error |
| flags.]</i></p> |
| |
| |
| <p><i>[Post-Sydney: Howard provided a new proposed resolution. The |
| old one didn't make sense because it proposed to fix this at the |
| level of basic_filebuf, which doesn't have access to the stream's |
| error state. Howard's proposed resolution fixes this at the level |
| of the three fstream class template instead.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="410"></a>410. Missing semantics for stack and queue comparison operators</h3> |
| <p><b>Section:</b> 23.2.4.1 [list.cons], 23.2.4.3 [list.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Hans Bos <b>Date:</b> 2003-06-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#list.cons">issues</a> in [list.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Sections 23.2.4.1 [list.cons] and 23.2.4.3 [list.modifiers] list |
| comparison operators (==, !=, <, <=, >, =>) for queue and |
| stack. Only the semantics for queue::operator== (23.2.4.1 [list.cons] par2) and queue::operator< (23.2.4.1 [list.cons] |
| par3) are defined. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add the following new paragraphs after 23.2.4.1 [list.cons] |
| paragraph 3:</p> |
| |
| <blockquote> |
| |
| <pre> operator!= |
| </pre> |
| <p>Returns: <tt>x.c != y.c</tt></p> |
| |
| <pre> operator> |
| </pre> |
| <p>Returns: <tt>x.c > y.c</tt></p> |
| |
| <pre> operator<= |
| </pre> |
| <p>Returns: <tt>x.c <= y.c</tt></p> |
| |
| <pre> operator>= |
| </pre> |
| <p>Returns: <tt>x.c >= y.c</tt></p> |
| |
| </blockquote> |
| |
| <p>Add the following paragraphs at the end of 23.2.4.3 [list.modifiers]:</p> |
| |
| <blockquote> |
| |
| <pre> operator== |
| </pre> |
| <p>Returns: <tt>x.c == y.c</tt></p> |
| |
| <pre> operator< |
| </pre> |
| <p>Returns: <tt>x.c < y.c</tt></p> |
| |
| <pre> operator!= |
| </pre> |
| <p>Returns: <tt>x.c != y.c</tt></p> |
| |
| <pre> operator> |
| </pre> |
| <p>Returns: <tt>x.c > y.c</tt></p> |
| |
| <pre> operator<= |
| </pre> |
| <p>Returns: <tt>x.c <= y.c</tt></p> |
| |
| <pre> operator>= |
| </pre> |
| <p>Returns: <tt>x.c >= y.c</tt></p> |
| |
| </blockquote> |
| |
| |
| <p><i>[Kona: Matt provided wording.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>There isn't any real doubt about what these operators are |
| supposed to do, but we ought to spell it out.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="411"></a>411. Wrong names of set member functions</h3> |
| <p><b>Section:</b> 25.3.5 [alg.set.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Frey <b>Date:</b> 2003-07-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.set.operations">issues</a> in [alg.set.operations].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 25.3.5 [alg.set.operations] paragraph 1 reads: |
| "The semantics of the set operations are generalized to multisets in a |
| standard way by defining union() to contain the maximum number of |
| occurrences of every element, intersection() to contain the minimum, and |
| so on." |
| </p> |
| |
| <p> |
| This is wrong. The name of the functions are set_union() and |
| set_intersection(), not union() and intersection(). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change that sentence to use the correct names.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="412"></a>412. Typo in 27.4.4.3</h3> |
| <p><b>Section:</b> 27.4.4.3 [iostate.flags] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-07-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostate.flags">issues</a> in [iostate.flags].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#429">429</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The Effects clause in 27.4.4.3 [iostate.flags] paragraph 5 says that the |
| function only throws if the respective bits are already set prior to |
| the function call. That's obviously not the intent. The typo ought to |
| be corrected and the text reworded as: "If (<i>state</i> & |
| exceptions()) == 0, returns. ..." |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.4.4.3 [iostate.flags] paragraph 5, replace "If (rdstate() & |
| exceptions()) == 0" with "If ((state | (rdbuf() ? goodbit : badbit)) |
| & exceptions()) == 0". |
| </p> |
| |
| <p><i>[Kona: the original proposed resolution wasn't quite right. We |
| really do mean rdstate(); the ambiguity is that the wording in the |
| standard doesn't make it clear whether we mean rdstate() before |
| setting the new state, or rdsate() after setting it. We intend the |
| latter, of course. Post-Kona: Martin provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="413"></a>413. Proposed resolution to LDR#64 still wrong</h3> |
| <p><b>Section:</b> 27.6.1.2.3 [istream::extractors] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Bo Persson <b>Date:</b> 2003-07-13</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream::extractors">issues</a> in [istream::extractors].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The second sentence of the proposed resolution says: |
| </p> |
| |
| <p> |
| "If it inserted no characters because it caught an exception thrown |
| while extracting characters from sb and ..." |
| </p> |
| |
| <p> |
| However, we are not extracting from sb, but extracting from the |
| basic_istream (*this) and inserting into sb. I can't really tell if |
| "extracting" or "sb" is a typo. |
| </p> |
| |
| <p><i>[ |
| Sydney: Definitely a real issue. We are, indeed, extracting characters |
| from an istream and not from sb. The problem was there in the FDIS and |
| wasn't fixed by issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#64">64</a>. Probably what was intended was |
| to have *this instead of sb. We're talking about the exception flag |
| state of a basic_istream object, and there's only one basic_istream |
| object in this discussion, so that would be a consistent |
| interpretation. (But we need to be careful: the exception policy of |
| this member function must be consistent with that of other |
| extractors.) PJP will provide wording. |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the sentence from:</p> |
| |
| <blockquote><p> |
| If it inserted no characters because it caught an exception thrown |
| while extracting characters from sb and failbit is on in exceptions(), |
| then the caught exception is rethrown. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| If it inserted no characters because it caught an exception thrown |
| while extracting characters from *this and failbit is on in exceptions(), |
| then the caught exception is rethrown. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="414"></a>414. Which iterators are invalidated by v.erase()?</h3> |
| <p><b>Section:</b> 23.2.6.4 [vector.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2003-08-19</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.modifiers">issues</a> in [vector.modifiers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Consider the following code fragment: |
| </p> |
| <blockquote> |
| <pre>int A[8] = { 1,3,5,7,9,8,4,2 }; |
| std::vector<int> v(A, A+8); |
| |
| std::vector<int>::iterator i1 = v.begin() + 3; |
| std::vector<int>::iterator i2 = v.begin() + 4; |
| v.erase(i1); |
| </pre> |
| </blockquote> |
| |
| <p> |
| Which iterators are invalidated by <tt>v.erase(i1)</tt>: i1, i2, |
| both, or neither? |
| </p> |
| |
| <p> |
| On all existing implementations that I know of, the status of i1 and |
| i2 is the same: both of them will be iterators that point to some |
| elements of the vector (albeit not the same elements they did |
| before). You won't get a crash if you use them. Depending on |
| exactly what you mean by "invalidate", you might say that neither one |
| has been invalidated because they still point to <i>something</i>, |
| or you might say that both have been invalidated because in both |
| cases the elements they point to have been changed out from under the |
| iterator. |
| </p> |
| |
| <p> |
| The standard doesn't say either of those things. It says that erase |
| invalidates all iterators and references "after the point of the |
| erase". This doesn't include i1, since it's at the point of the |
| erase instead of after it. I can't think of any sensible definition |
| of invalidation by which one can say that i2 is invalidated but i1 |
| isn't. |
| </p> |
| |
| <p> |
| (This issue is important if you try to reason about iterator validity |
| based only on the guarantees in the standard, rather than reasoning |
| from typical implementation techniques. Strict debugging modes, |
| which some programmers find useful, do not use typical implementation |
| techniques.) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 23.2.6.4 [vector.modifiers] paragraph 3, change "Invalidates all the |
| iterators and references after the point of the erase" to |
| "Invalidates iterators and references at or after the point of the |
| erase". |
| </p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>I believe this was essentially a typographical error, and that it |
| was taken for granted that erasing an element invalidates iterators |
| that point to it. The effects clause in question treats iterators |
| and references in parallel, and it would seem counterintuitive to |
| say that a reference to an erased value remains valid.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="415"></a>415. behavior of std::ws</h3> |
| <p><b>Section:</b> 27.6.1.4 [istream.manip] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| According to 27.6.1.4, the ws() manipulator is not required to construct |
| the sentry object. The manipulator is also not a member function so the |
| text in 27.6.1, p1 through 4 that describes the exception policy for |
| istream member functions does not apply. That seems inconsistent with |
| the rest of extractors and all the other input functions (i.e., ws will |
| not cause a tied stream to be flushed before extraction, it doesn't check |
| the stream's exceptions or catch exceptions thrown during input, and it |
| doesn't affect the stream's gcount). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 27.6.1.4 [istream.manip], immediately before the first sentence |
| of paragraph 1, the following text: |
| </p> |
| |
| <blockquote><p> |
| Behaves as an unformatted input function (as described in |
| 27.6.1.3, paragraph 1), except that it does not count the number |
| of characters extracted and does not affect the value returned by |
| subsequent calls to is.gcount(). After constructing a sentry |
| object... |
| </p></blockquote> |
| |
| <p><i>[Post-Kona: Martin provided wording]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="416"></a>416. definitions of XXX_MIN and XXX_MAX macros in climits</h3> |
| <p><b>Section:</b> 18.2.2 [c.limits] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| Given two overloads of the function foo(), one taking an argument of type |
| int and the other taking a long, which one will the call foo(LONG_MAX) |
| resolve to? The expected answer should be foo(long), but whether that |
| is true depends on the #defintion of the LONG_MAX macro, specifically |
| its type. This issue is about the fact that the type of these macros |
| is not actually required to be the same as the the type each respective |
| limit. |
| <br> |
| |
| Section 18.2.2 of the C++ Standard does not specify the exact types of |
| the XXX_MIN and XXX_MAX macros #defined in the <climits> and <limits.h> |
| headers such as INT_MAX and LONG_MAX and instead defers to the C standard. |
| <br> |
| |
| Section 5.2.4.2.1, p1 of the C standard specifies that "The values [of |
| these constants] shall be replaced by constant expressions suitable for use |
| in #if preprocessing directives. Moreover, except for CHAR_BIT and MB_LEN_MAX, |
| the following shall be replaced by expressions that have the same type as |
| would an expression that is an object of the corresponding type converted |
| according to the integer promotions." |
| <br> |
| |
| The "corresponding type converted according to the integer promotions" for |
| LONG_MAX is, according to 6.4.4.1, p5 of the C standard, the type of long |
| converted to the first of the following set of types that can represent it: |
| int, long int, long long int. So on an implementation where (sizeof(long) |
| == sizeof(int)) this type is actually int, while on an implementation where |
| (sizeof(long) > sizeof(int)) holds this type will be long. |
| <br> |
| |
| This is not an issue in C since the type of the macro cannot be detected |
| by any conforming C program, but it presents a portability problem in C++ |
| where the actual type is easily detectable by overload resolution. |
| |
| </p> |
| <p><i>[Kona: the LWG does not believe this is a defect. The C macro |
| definitions are what they are; we've got a better |
| mechanism, <tt>std::numeric_limits</tt>, that is specified more |
| precisely than the C limit macros. At most we should add a |
| nonnormative note recommending that users who care about the exact |
| types of limit quantities should use <limits> instead of |
| <climits>.]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change 18.2.2 [c.limits], paragraph 2: |
| </p> |
| |
| <blockquote><p> |
| -2- The contents are the same as the Standard C library header <tt><limits.h></tt>. |
| <ins>[<i>Note:</i> The types of the macros in <tt><climits></tt> are not guaranteed |
| to match the type to which they refer.<i>--end note</i>]</ins> |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="420"></a>420. is std::FILE a complete type?</h3> |
| <p><b>Section:</b> 27.8.1 [fstreams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#fstreams">issues</a> in [fstreams].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 7.19.1, p2, of C99 requires that the FILE type only be declared in |
| <stdio.h>. None of the (implementation-defined) members of the |
| struct is mentioned anywhere for obvious reasons. |
| </p> |
| |
| <p> |
| C++ says in 27.8.1, p2 that FILE is a type that's defined in <cstdio>. Is |
| it really the intent that FILE be a complete type or is an implementation |
| allowed to just declare it without providing a full definition? |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In the first sentence of 27.8.1 [fstreams] paragraph 2, change |
| "defined" to "declared".</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>We don't want to impose any restrictions beyond what the C standard |
| already says. We don't want to make anything implementation defined, |
| because that imposes new requirements in implementations.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="422"></a>422. explicit specializations of member functions of class templates</h3> |
| <p><b>Section:</b> 17.4.3.2 [reserved.names] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#reserved.names">issues</a> in [reserved.names].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It has been suggested that 17.4.3.1, p1 may or may not allow programs to |
| explicitly specialize members of standard templates on user-defined types. |
| The answer to the question might have an impact where library requirements |
| are given using the "as if" rule. I.e., if programs are allowed to specialize |
| member functions they will be able to detect an implementation's strict |
| conformance to Effects clauses that describe the behavior of the function |
| in terms of the other member function (the one explicitly specialized by |
| the program) by relying on the "as if" rule. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Add the following sentence to 17.4.3.2 [reserved.names], p1: |
| </p> |
| |
| <blockquote><p> |
| It is undefined for a C++ program to add declarations or definitions to |
| namespace std or namespaces within namespace <tt>std</tt> unless otherwise specified. A |
| program may add template specializations for any standard library template to |
| namespace <tt>std</tt>. Such a specialization (complete or partial) of a standard library |
| template results in undefined behavior unless the declaration depends on a |
| user-defined type of external linkage and unless the specialization meets the |
| standard library requirements for the original template.<sup>168)</sup> |
| <ins>A program has undefined behavior if it declares</ins> |
| </p> |
| <ul> |
| <li><ins>an explicit specialization of any member function of a standard |
| library class template, or</ins></li> |
| <li><ins>an explicit specialization of any member function template of a |
| standard library class or class template, or</ins></li> |
| <li><ins>an explicit or partial specialization of any member class |
| template of a standard library class or class template.</ins></li> |
| </ul> |
| <p> |
| A program may explicitly instantiate any templates in the standard library only |
| if the declaration depends on the name of a user-defined type of external |
| linkage and the instantiation meets the standard library requirements for the |
| original template. |
| </p></blockquote> |
| |
| <p><i>[Kona: straw poll was 6-1 that user programs should not be |
| allowed to specialize individual member functions of standard |
| library class templates, and that doing so invokes undefined |
| behavior. Post-Kona: Martin provided wording.]</i></p> |
| |
| |
| <p><i>[Sydney: The LWG agrees that the standard shouldn't permit users |
| to specialize individual member functions unless they specialize the |
| whole class, but we're not sure these words say what we want them to; |
| they could be read as prohibiting the specialization of any standard |
| library class templates. We need to consult with CWG to make sure we |
| use the right wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="425"></a>425. return value of std::get_temporary_buffer</h3> |
| <p><b>Section:</b> 20.7.8 [temporary.buffer] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The standard is not clear about the requirements on the value returned from |
| a call to get_temporary_buffer(0). In particular, it fails to specify whether |
| the call should return a distinct pointer each time it is called (like |
| operator new), or whether the value is unspecified (as if returned by |
| malloc). The standard also fails to mention what the required behavior |
| is when the argument is less than 0. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 20.5.3 [meta.help] paragraph 2 from "...or a pair of 0 |
| values if no storage can be obtained" to "...or a pair of 0 values if |
| no storage can be obtained or if <i>n</i> <= 0."</p> |
| <p><i>[Kona: Matt provided wording]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="426"></a>426. search_n(), fill_n(), and generate_n() with negative n</h3> |
| <p><b>Section:</b> 25.1.12 [alg.search], 25.2.6 [alg.fill], 25.2.7 [alg.generate] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.search">issues</a> in [alg.search].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The complexity requirements for these function templates are incorrect |
| (or don't even make sense) for negative n:</p> |
| |
| <p>25.1.9, p7 (search_n): |
| <br> |
| Complexity: At most (last1 - first1) * count applications |
| of the corresponding predicate.</p> |
| |
| <p>25.2.5, p3 (fill_n): |
| <br> |
| Complexity: Exactly last - first (or n) assignments.</p> |
| |
| <p>25.2.6, p3 (generate_n): |
| <br> |
| Complexity: Exactly last - first (or n) assignments.</p> |
| |
| <p> |
| In addition, the Requirements or the Effects clauses for the latter two |
| templates don't say anything about the behavior when n is negative. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 25.1.9, p7 to</p> |
| |
| <blockquote><p> |
| Complexity: At most (last1 - first1) * count applications |
| of the corresponding predicate if count is positive, |
| or 0 otherwise. |
| </p></blockquote> |
| |
| <p>Change 25.2.5, p2 to</p> |
| <blockquote><p> |
| Effects: Assigns value through all the iterators in the range [first, |
| last), or [first, first + n) if n is positive, none otherwise. |
| </p></blockquote> |
| |
| <p>Change 25.2.5, p3 to:</p> |
| <blockquote><p> |
| Complexity: Exactly last - first (or n if n is positive, |
| or 0 otherwise) assignments. |
| </p></blockquote> |
| |
| <p> |
| Change 25.2.6, p1 |
| to (notice the correction for the misspelled "through"): |
| </p> |
| <blockquote><p> |
| Effects: Invokes the function object genand assigns the return |
| value of gen through all the iterators in the range [first, last), |
| or [first, first + n) if n is positive, or [first, first) |
| otherwise. |
| </p></blockquote> |
| |
| <p>Change 25.2.6, p3 to:</p> |
| <blockquote><p> |
| Complexity: Exactly last - first (or n if n is positive, |
| or 0 otherwise) assignments. |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Informally, we want to say that whenever we see a negative number |
| we treat it the same as if it were zero. We believe the above |
| changes do that (although they may not be the minimal way of saying |
| so). The LWG considered and rejected the alternative of saying that |
| negative numbers are undefined behavior.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="428"></a>428. string::erase(iterator) validity</h3> |
| <p><b>Section:</b> 21.3.6.5 [string::erase] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-09-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::erase">issues</a> in [string::erase].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 23.1.1, p3 along with Table 67 specify as a prerequisite for a.erase(q) |
| that q must be a valid dereferenceable iterator into the sequence a. |
| </p> |
| |
| <p> |
| However, 21.3.5.5, p5 describing string::erase(p) only requires that |
| p be a valid iterator. |
| </p> |
| |
| <p> |
| This may be interepreted as a relaxation of the general requirement, |
| which is most likely not the intent. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Remove 21.3.6.5 [string::erase] paragraph 5.</p> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG considered two options: changing the string requirements to |
| match the general container requirements, or just removing the |
| erroneous string requirements altogether. The LWG chose the latter |
| option, on the grounds that duplicating text always risks the |
| possibility that it might be duplicated incorrectly.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="432"></a>432. stringbuf::overflow() makes only one write position available</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Christian W Brock <b>Date:</b> 2003-09-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.7.1.3 par 8 says:</p> |
| <blockquote><p> |
| Notes: The function can make a write position available only if |
| ( mode & ios_base::out) != 0. To make a write position |
| available, the function reallocates (or initially allocates) an |
| array object with a sufficient number of elements to hold the |
| current array object (if any), plus one additional write position. |
| If ( mode & ios_base::in) != 0, the function alters the read end |
| pointer egptr() to point just past the new write position (as |
| does the write end pointer epptr()). |
| </p></blockquote> |
| |
| <p> |
| The sentences "plus one additional write position." and especially |
| "(as does the write end pointer epptr())" COULD by interpreted |
| (and is interpreted by at least my library vendor) as: |
| </p> |
| |
| <blockquote><p> |
| post-condition: epptr() == pptr()+1 |
| </p></blockquote> |
| |
| <p> |
| This WOULD force sputc() to call the virtual overflow() each time. |
| </p> |
| |
| <p>The proposed change also affects Defect Report 169.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>27.7.1.1/2 Change:</p> |
| |
| <blockquote><p> |
| 2- Notes: The function allocates no array object. |
| </p></blockquote> |
| |
| <p> |
| to: |
| </p> |
| |
| <blockquote><p> |
| 2- Postcondition: str() == "". |
| </p></blockquote> |
| |
| <p> |
| 27.7.1.1/3 Change: |
| </p> |
| |
| <blockquote> |
| <p> |
| -3- Effects: Constructs an object of class basic_stringbuf, |
| initializing the base class with basic_streambuf() |
| (lib.streambuf.cons), and initializing mode with which . Then copies |
| the content of str into the basic_stringbuf underlying character |
| sequence and initializes the input and output sequences according to |
| which. If which & ios_base::out is true, initializes the output |
| sequence with the underlying sequence. If which & ios_base::in is |
| true, initializes the input sequence with the underlying sequence. |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -3- Effects: Constructs an object of class basic_stringbuf, |
| initializing the base class with basic_streambuf() |
| (lib.streambuf.cons), and initializing mode with which. Then copies |
| the content of str into the basic_stringbuf underlying character |
| sequence. If which & ios_base::out is true, initializes the output |
| sequence such that pbase() points to the first underlying character, |
| epptr() points one past the last underlying character, and if (which & |
| ios_base::ate) is true, pptr() is set equal to |
| epptr() else pptr() is set equal to pbase(). If which & ios_base::in |
| is true, initializes the input sequence such that eback() and gptr() |
| point to the first underlying character and egptr() points one past |
| the last underlying character. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.2/1 Change:</p> |
| |
| <blockquote> |
| <p> |
| -1- Returns: A basic_string object whose content is equal to the |
| basic_stringbuf underlying character sequence. If the buffer is only |
| created in input mode, the underlying character sequence is equal to |
| the input sequence; otherwise, it is equal to the output sequence. In |
| case of an empty underlying character sequence, the function returns |
| basic_string<charT,traits,Allocator>(). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -1- Returns: A basic_string object whose content is equal to the |
| basic_stringbuf underlying character sequence. If the basic_stringbuf |
| was created only in input mode, the resultant basic_string contains |
| the character sequence in the range [eback(), egptr()). If the |
| basic_stringbuf was created with (which & ios_base::out) being true |
| then the resultant basic_string contains the character sequence in the |
| range [pbase(), high_mark) where high_mark represents the position one |
| past the highest initialized character in the buffer. Characters can |
| be initialized either through writing to the stream, or by |
| constructing the basic_stringbuf with a basic_string, or by calling |
| the str(basic_string) member function. In the case of calling the |
| str(basic_string) member function, all characters initialized prior to |
| the call are now considered uninitialized (except for those |
| characters re-initialized by the new basic_string). Otherwise the |
| basic_stringbuf has been created in neither input nor output mode and |
| a zero length basic_string is returned. |
| </p> |
| </blockquote> |
| |
| <p> |
| 27.7.1.2/2 Change: |
| </p> |
| |
| <blockquote> |
| <p> |
| -2- Effects: If the basic_stringbuf's underlying character sequence is |
| not empty, deallocates it. Then copies the content of s into the |
| basic_stringbuf underlying character sequence and initializes the |
| input and output sequences according to the mode stored when creating |
| the basic_stringbuf object. If (mode&ios_base::out) is true, then |
| initializes the output sequence with the underlying sequence. If |
| (mode&ios_base::in) is true, then initializes the input sequence with |
| the underlying sequence. |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -2- Effects: Copies the content of s into the basic_stringbuf |
| underlying character sequence. If mode & ios_base::out is true, |
| initializes the output sequence such that pbase() points to the first |
| underlying character, epptr() points one past the last underlying |
| character, and if (mode & ios_base::ate) is true, |
| pptr() is set equal to epptr() else pptr() is set equal to pbase(). If |
| mode & ios_base::in is true, initializes the input sequence such that |
| eback() and gptr() point to the first underlying character and egptr() |
| points one past the last underlying character. |
| </p> |
| </blockquote> |
| |
| <p>Remove 27.2.1.2/3. (Same rationale as issue 238: incorrect and unnecessary.)</p> |
| |
| <p>27.7.1.3/1 Change:</p> |
| |
| <blockquote> |
| <p> |
| 1- Returns: If the input sequence has a read position available, |
| returns traits::to_int_type(*gptr()). Otherwise, returns |
| traits::eof(). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| 1- Returns: If the input sequence has a read position available, |
| returns traits::to_int_type(*gptr()). Otherwise, returns |
| traits::eof(). Any character in the underlying buffer which has been |
| initialized is considered to be part of the input sequence. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.3/9 Change:</p> |
| |
| <blockquote> |
| <p> |
| -9- Notes: The function can make a write position available only if ( |
| mode & ios_base::out) != 0. To make a write position available, the |
| function reallocates (or initially allocates) an array object with a |
| sufficient number of elements to hold the current array object (if |
| any), plus one additional write position. If ( mode & ios_base::in) != |
| 0, the function alters the read end pointer egptr() to point just past |
| the new write position (as does the write end pointer epptr()). |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -9- The function can make a write position available only if ( mode & |
| ios_base::out) != 0. To make a write position available, the function |
| reallocates (or initially allocates) an array object with a sufficient |
| number of elements to hold the current array object (if any), plus one |
| additional write position. If ( mode & ios_base::in) != 0, the |
| function alters the read end pointer egptr() to point just past the |
| new write position. |
| </p> |
| </blockquote> |
| |
| <p>27.7.1.3/12 Change:</p> |
| |
| <blockquote> |
| <p> |
| -12- _ If (newoff + off) < 0, or (xend - xbeg) < (newoff + off), the |
| positioning operation fails. Otherwise, the function assigns xbeg + |
| newoff + off to the next pointer xnext . |
| </p> |
| </blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote> |
| <p> |
| -12- _ If (newoff + off) < 0, or if (newoff + off) refers to an |
| uninitialized character (as defined in 27.7.1.3 [stringbuf.members] |
| paragraph 1), the positioning operation fails. Otherwise, the function |
| assigns xbeg + newoff + off to the next pointer xnext . |
| </p> |
| </blockquote> |
| |
| <p><i>[post-Kona: Howard provided wording. At Kona the LWG agreed that |
| something along these lines was a good idea, but the original |
| proposed resolution didn't say enough about the effect of various |
| member functions on the underlying character sequences.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The current basic_stringbuf description is over-constrained in such |
| a way as to prohibit vendors from making this the high-performance |
| in-memory stream it was meant to be. The fundamental problem is that |
| the pointers: eback(), gptr(), egptr(), pbase(), pptr(), epptr() are |
| observable from a derived client, and the current description |
| restricts the range [pbase(), epptr()) from being grown geometrically. |
| This change allows, but does not require, geometric growth of this |
| range.</p> |
| |
| <p>Backwards compatibility issues: These changes will break code that |
| derives from basic_stringbuf, observes epptr(), and depends upon |
| [pbase(), epptr()) growing by one character on each call to overflow() |
| (i.e. test suites). Otherwise there are no backwards compatibility |
| issues.</p> |
| |
| <p>27.7.1.1/2: The non-normative note is non-binding, and if it were |
| binding, would be over specification. The recommended change focuses |
| on the important observable fact.</p> |
| |
| <p>27.7.1.1/3: This change does two things: 1. It describes exactly |
| what must happen in terms of the sequences. The terms "input |
| sequence" and "output sequence" are not well defined. 2. It |
| introduces a common extension: open with app or ate mode. I concur |
| with issue 238 that paragraph 4 is both wrong and unnecessary.</p> |
| |
| <p>27.7.1.2/1: This change is the crux of the efficiency issue. The |
| resultant basic_string is not dependent upon epptr(), and thus |
| implementors are free to grow the underlying buffer geometrically |
| during overflow() *and* place epptr() at the end of that buffer.</p> |
| |
| <p>27.7.1.2/2: Made consistent with the proposed 27.7.1.1/3.</p> |
| |
| <p>27.7.1.3/1: Clarifies that characters written to the stream beyond |
| the initially specified string are available for reading in an i/o |
| basic_streambuf.</p> |
| |
| <p>27.7.1.3/9: Made normative by removing "Notes:", and removed the |
| trailing parenthetical comment concerning epptr().</p> |
| |
| <p>27.7.1.3/12: Restricting the positioning to [xbeg, xend) is no |
| longer allowable since [pbase(), epptr()) may now contain |
| uninitialized characters. Positioning is only allowable over the |
| initialized range.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="434"></a>434. bitset::to_string() hard to use</h3> |
| <p><b>Section:</b> 23.3.5.2 [bitset.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-10-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#bitset.members">issues</a> in [bitset.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It has been pointed out a number of times that the bitset to_string() member |
| function template is tedious to use since callers must explicitly specify the |
| entire template argument list (3 arguments). At least two implementations |
| provide a number of overloads of this template to make it easier to use. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In order to allow callers to specify no template arguments at all, just the |
| first one (charT), or the first 2 (charT and traits), in addition to all |
| three template arguments, add the following three overloads to both the |
| interface (declarations only) of the class template bitset as well as to |
| section 23.3.5.2, immediately after p34, the Returns clause of the existing |
| to_string() member function template:</p> |
| |
| <pre> template <class charT, class traits> |
| basic_string<charT, traits, allocator<charT> > |
| to_string () const; |
| |
| -34.1- Returns: to_string<charT, traits, allocator<charT> >(). |
| |
| template <class charT> |
| basic_string<charT, char_traits<charT>, allocator<charT> > |
| to_string () const; |
| |
| -34.2- Returns: to_string<charT, char_traits<charT>, allocator<charT> >(). |
| |
| basic_string<char, char_traits<char>, allocator<char> > |
| to_string () const; |
| |
| -34.3- Returns: to_string<char, char_traits<char>, allocator<char> >(). |
| </pre> |
| |
| <p><i>[Kona: the LWG agrees that this is an improvement over the |
| status quo. Dietmar thought about an alternative using a proxy |
| object but now believes that the proposed resolution above is the |
| right choice. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="435"></a>435. bug in DR 25</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-10-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| It has been pointed out that the proposed resolution in DR 25 may not be |
| quite up to snuff: <br> |
| http://gcc.gnu.org/ml/libstdc++/2003-09/msg00147.html |
| http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/lwg-defects.html#25<br> |
| </p> |
| |
| <p> |
| It looks like Petur is right. The complete corrected text is copied below. |
| I think we may have have been confused by the reference to 22.2.2.2.2 and |
| the subsequent description of `n' which actually talks about the second |
| argument to sputn(), not about the number of fill characters to pad with. |
| </p> |
| |
| <p> |
| So the question is: was the original text correct? If the intent was to |
| follow classic iostreams then it most likely wasn't, since setting width() |
| to less than the length of the string doesn't truncate it on output. This |
| is also the behavior of most implementations (except for SGI's standard |
| iostreams where the operator does truncate). |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the text in 21.3.7.9, p4 from</p> |
| <blockquote><p> |
| If bool(k) is true, inserts characters as if by calling |
| os.rdbuf()->sputn(str.data(), n), padding as described in stage 3 |
| of lib.facet.num.put.virtuals, where n is the larger of os.width() |
| and str.size(); |
| </p></blockquote> |
| <p>to</p> |
| <blockquote><p> |
| If bool(k) is true, determines padding as described in |
| lib.facet.num.put.virtuals, and then inserts the resulting |
| sequence of characters <tt>seq</tt> as if by calling |
| <tt>os.rdbuf()->sputn(seq, n)</tt>, where <tt>n</tt> is the larger of |
| <tt>os.width()</tt> and <tt>str.size()</tt>; |
| </p></blockquote> |
| |
| <p><i>[Kona: it appears that neither the original wording, DR25, nor the |
| proposed resolution, is quite what we want. We want to say that |
| the string will be output, padded to os.width() if necessary. We |
| don't want to duplicate the padding rules in clause 22, because |
| they're complicated, but we need to be careful because they weren't |
| quite written with quite this case in mind. We need to say what |
| the character sequence is, and then defer to clause 22. Post-Kona: |
| Benjamin provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="436"></a>436. are cv-qualified facet types valid facets?</h3> |
| <p><b>Section:</b> 22.1.1.1.2 [locale.facet] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2003-10-15</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Is "const std::ctype<char>" a valid template argument to has_facet, use_facet, |
| and the locale template ctor? And if so, does it designate the same Facet as |
| the non-const "std::ctype<char>?" What about "volatile std::ctype<char>?" |
| Different implementations behave differently: some fail to compile, others |
| accept such types but behave inconsistently. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 22.1.1.1.2, p1 to read:</p> |
| |
| <p>Template parameters in this clause which are required to be facets |
| are those named Facet in declarations. A program that passes a type |
| that is not a facet, or a type that refers to volatile-qualified |
| facet, as an (explicit or deduced) template parameter to a locale |
| function expecting a facet, is ill-formed. A const-qualified facet is |
| a valid template argument to any locale function that expects a Facet |
| template parameter.</p> |
| |
| <p><i>[Kona: changed the last sentence from a footnote to normative |
| text.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="438"></a>438. Ambiguity in the "do the right thing" clause</h3> |
| <p><b>Section:</b> 23.1.3 [sequence.reqmts] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2003-10-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#sequence.reqmts">issues</a> in [sequence.reqmts].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>Section 23.1.3 [sequence.reqmts], paragraphs 9-11, fixed up the problem |
| noticed with statements like:</p> |
| <pre>vector<int> v(10, 1); |
| </pre> |
| |
| <p>The intent of the above statement was to construct with:</p> |
| <pre>vector(size_type, const value_type&); |
| </pre> |
| |
| <p>but early implementations failed to compile as they bound to:</p> |
| <pre>template <class InputIterator> |
| vector(InputIterator f, InputIterator l); |
| </pre> |
| <p>instead.</p> |
| |
| <p>Paragraphs 9-11 say that if InputIterator is an integral type, then the |
| member template constructor will have the same effect as:</p> |
| <pre>vector<static_cast<size_type>(f), static_cast<value_type>(l)); |
| </pre> |
| <p>(and similarly for the other member template functions of sequences).</p> |
| |
| <p>There is also a note that describes one implementation technique:</p> |
| <blockquote><p> |
| One way that sequence implementors can satisfy this requirement is to |
| specialize the member template for every integral type. |
| </p></blockquote> |
| |
| <p>This might look something like:</p> |
| <blockquote> |
| <pre>template <class T> |
| struct vector |
| { |
| typedef unsigned size_type; |
| |
| explicit vector(size_type) {} |
| vector(size_type, const T&) {} |
| |
| template <class I> |
| vector(I, I); |
| |
| // ... |
| }; |
| |
| template <class T> |
| template <class I> |
| vector<T>::vector(I, I) { ... } |
| |
| template <> |
| template <> |
| vector<int>::vector(int, int) { ... } |
| |
| template <> |
| template <> |
| vector<int>::vector(unsigned, unsigned) { ... } |
| |
| // ... |
| </pre> |
| </blockquote> |
| |
| <p>Label this solution 'A'.</p> |
| |
| <p>The standard also says:</p> |
| <blockquote><p> |
| Less cumbersome implementation techniques also exist. |
| </p></blockquote> |
| <p> |
| A popular technique is to not specialize as above, but instead catch |
| every call with the member template, detect the type of InputIterator, |
| and then redirect to the correct logic. Something like: |
| </p> |
| <blockquote> |
| <pre>template <class T> |
| template <class I> |
| vector<T>::vector(I f, I l) |
| { |
| choose_init(f, l, int2type<is_integral<I>::value>()); |
| } |
| |
| template <class T> |
| template <class I> |
| vector<T>::choose_init(I f, I l, int2type<false>) |
| { |
| // construct with iterators |
| } |
| |
| template <class T> |
| template <class I> |
| vector<T>::choose_init(I f, I l, int2type<true>) |
| { |
| size_type sz = static_cast<size_type>(f); |
| value_type v = static_cast<value_type>(l); |
| // construct with sz,v |
| } |
| </pre> |
| </blockquote> |
| |
| <p>Label this solution 'B'.</p> |
| |
| <p>Both of these solutions solve the case the standard specifically |
| mentions:</p> |
| <pre>vector<int> v(10, 1); // ok, vector size 10, initialized to 1 |
| </pre> |
| |
| <p> |
| However, (and here is the problem), the two solutions have different |
| behavior in some cases where the value_type of the sequence is not an |
| integral type. For example consider: |
| </p> |
| <blockquote><pre> pair<char, char> p('a', 'b'); |
| vector<vector<pair<char, char> > > d('a', 'b'); |
| </pre></blockquote> |
| <p> |
| The second line of this snippet is likely an error. Solution A catches |
| the error and refuses to compile. The reason is that there is no |
| specialization of the member template constructor that looks like: |
| </p> |
| <pre>template <> |
| template <> |
| vector<vector<pair<char, char> > >::vector(char, char) { ... } |
| </pre> |
| |
| <p> |
| So the expression binds to the unspecialized member template |
| constructor, and then fails (compile time) because char is not an |
| InputIterator. |
| </p> |
| |
| <p> |
| Solution B compiles the above example though. 'a' is casted to an |
| unsigned integral type and used to size the outer vector. 'b' is |
| static casted to the inner vector using it's explicit constructor: |
| </p> |
| |
| <pre>explicit vector(size_type n); |
| </pre> |
| |
| <p> |
| and so you end up with a static_cast<size_type>('a') by |
| static_cast<size_type>('b') matrix. |
| </p> |
| |
| <p> |
| It is certainly possible that this is what the coder intended. But the |
| explicit qualifier on the inner vector has been thwarted at any rate. |
| </p> |
| |
| <p> |
| The standard is not clear whether the expression: |
| </p> |
| |
| <pre> vector<vector<pair<char, char> > > d('a', 'b'); |
| </pre> |
| |
| <p> |
| (and similar expressions) are: |
| </p> |
| |
| <ol> |
| <li> undefined behavior.</li> |
| <li> illegal and must be rejected.</li> |
| <li> legal and must be accepted.</li> |
| </ol> |
| |
| <p>My preference is listed in the order presented.</p> |
| |
| <p>There are still other techniques for implementing the requirements of |
| paragraphs 9-11, namely the "restricted template technique" (e.g. |
| enable_if). This technique is the most compact and easy way of coding |
| the requirements, and has the behavior of #2 (rejects the above |
| expression). |
| </p> |
| |
| <p> |
| Choosing 1 would allow all implementation techniques I'm aware of. |
| Choosing 2 would allow only solution 'A' and the enable_if technique. |
| Choosing 3 would allow only solution 'B'. |
| </p> |
| |
| <p> |
| Possible wording for a future standard if we wanted to actively reject |
| the expression above would be to change "static_cast" in paragraphs |
| 9-11 to "implicit_cast" where that is defined by: |
| </p> |
| |
| <blockquote> |
| <pre>template <class T, class U> |
| inline |
| T implicit_cast(const U& u) |
| { |
| return u; |
| } |
| </pre> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Replace 23.1.3 [sequence.reqmts] paragraphs 9 - 11 with:</p> |
| |
| <p>For every sequence defined in this clause and in clause lib.strings:</p> |
| |
| <ul> |
| <li> |
| <p>If the constructor</p> |
| <pre> template <class InputIterator> |
| X(InputIterator f, InputIterator l, |
| const allocator_type& a = allocator_type()) |
| </pre> |
| <p>is called with a type InputIterator that does not qualify as |
| an input iterator, then the constructor will behave as if the |
| overloaded constructor:</p> |
| <pre> X(size_type, const value_type& = value_type(), |
| const allocator_type& = allocator_type()) |
| </pre> |
| <p>were called instead, with the arguments static_cast<size_type>(f), l and a, respectively.</p> |
| </li> |
| |
| <li> |
| <p>If the member functions of the forms:</p> |
| <pre> template <class InputIterator> // such as insert() |
| rt fx1(iterator p, InputIterator f, InputIterator l); |
| |
| template <class InputIterator> // such as append(), assign() |
| rt fx2(InputIterator f, InputIterator l); |
| |
| template <class InputIterator> // such as replace() |
| rt fx3(iterator i1, iterator i2, InputIterator f, InputIterator l); |
| </pre> |
| <p>are called with a type InputIterator that does not qualify as |
| an input iterator, then these functions will behave as if the |
| overloaded member functions:</p> |
| <pre> rt fx1(iterator, size_type, const value_type&); |
| |
| rt fx2(size_type, const value_type&); |
| |
| rt fx3(iterator, iterator, size_type, const value_type&); |
| </pre> |
| <p>were called instead, with the same arguments.</p> |
| </li> |
| </ul> |
| |
| <p>In the previous paragraph the alternative binding will fail if f |
| is not implicitly convertible to X::size_type or if l is not implicitly |
| convertible to X::value_type.</p> |
| |
| <p> |
| The extent to which an implementation determines that a type cannot be |
| an input iterator is unspecified, except that as a minimum integral |
| types shall not qualify as input iterators. |
| </p> |
| |
| |
| |
| <p><i>[ |
| Kona: agreed that the current standard requires <tt>v('a', 'b')</tt> |
| to be accepted, and also agreed that this is surprising behavior. The |
| LWG considered several options, including something like |
| implicit_cast, which doesn't appear to be quite what we want. We |
| considered Howards three options: allow acceptance or rejection, |
| require rejection as a compile time error, and require acceptance. By |
| straw poll (1-6-1), we chose to require a compile time error. |
| Post-Kona: Howard provided wording. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Sydney: The LWG agreed with this general direction, but there was some |
| discomfort with the wording in the original proposed resolution. |
| Howard submitted new wording, and we will review this again in |
| Redmond. |
| ]</i></p> |
| |
| |
| <p><i>[Redmond: one very small change in wording: the first argument |
| is cast to size_t. This fixes the problem of something like |
| <tt>vector<vector<int> >(5, 5)</tt>, where int is not |
| implicitly convertible to the value type.]</i></p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The proposed resolution fixes:</p> |
| |
| <pre> vector<int> v(10, 1); |
| </pre> |
| |
| <p> |
| since as integral types 10 and 1 must be disqualified as input |
| iterators and therefore the (size,value) constructor is called (as |
| if).</p> |
| |
| <p>The proposed resolution breaks:</p> |
| |
| <pre> vector<vector<T> > v(10, 1); |
| </pre> |
| |
| <p> |
| because the integral type 1 is not *implicitly* convertible to |
| vector<T>. The wording above requires a diagnostic.</p> |
| |
| <p> |
| The proposed resolution leaves the behavior of the following code |
| unspecified. |
| </p> |
| |
| <pre> struct A |
| { |
| operator int () const {return 10;} |
| }; |
| |
| struct B |
| { |
| B(A) {} |
| }; |
| |
| vector<B> v(A(), A()); |
| </pre> |
| |
| <p> |
| The implementation may or may not detect that A is not an input |
| iterator and employee the (size,value) constructor. Note though that |
| in the above example if the B(A) constructor is qualified explicit, |
| then the implementation must reject the constructor as A is no longer |
| implicitly convertible to B. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="441"></a>441. Is fpos::state const?</h3> |
| <p><b>Section:</b> 27.4.3 [fpos] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Vincent Leloup <b>Date:</b> 2003-11-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#fpos">issues</a> in [fpos].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In section 27.4.3.1 [fpos.members] fpos<stateT>::state() is declared |
| non const, but in section 27.4.3 [fpos] it is declared const. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 27.4.3.1 [fpos.members], change the declaration of |
| <tt>fpos<stateT>::state()</tt> to const. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="442"></a>442. sentry::operator bool() inconsistent signature</h3> |
| <p><b>Section:</b> 27.6.2.4 [ostream::sentry] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Vincent Leloup <b>Date:</b> 2003-11-18</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#ostream::sentry">active issues</a> in [ostream::sentry].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream::sentry">issues</a> in [ostream::sentry].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In section 27.6.2.4 [ostream::sentry] paragraph 4, in description part |
| basic_ostream<charT, traits>::sentry::operator bool() is declared |
| as non const, but in section 27.6.2.3, in synopsis it is declared |
| const. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In section 27.6.2.4 [ostream::sentry] paragraph 4, change the declaration |
| of <tt>sentry::operator bool()</tt> to const. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="443"></a>443. filebuf::close() inconsistent use of EOF</h3> |
| <p><b>Section:</b> 27.8.1.4 [filebuf.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Vincent Leloup <b>Date:</b> 2003-11-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#filebuf.members">issues</a> in [filebuf.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In section 27.8.1.4 [filebuf.members] par6, in effects description of |
| basic_filebuf<charT, traits>::close(), overflow(EOF) is used twice; |
| should be overflow(traits::eof()). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change overflow(EOF) to overflow(traits::eof()). |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="444"></a>444. Bad use of casts in fstream</h3> |
| <p><b>Section:</b> 27.8.1 [fstreams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Vincent Leloup <b>Date:</b> 2003-11-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#fstreams">issues</a> in [fstreams].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>27.8.1.9 [ifstream.members] p1, 27.8.1.13 [ofstream.members] p1, |
| 27.8.1.17 [fstream.members] p1 seems have same problem as exposed in |
| LWG issue |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#252">252</a>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Sydney: Genuine defect. 27.8.1.13 needs a cast to cast away |
| constness. The other two places are stylistic: we could change the |
| C-style casts to const_cast. Post-Sydney: Howard provided wording. |
| ]</i></p> |
| |
| |
| <p>Change 27.8.1.7/1 from:</p> |
| <blockquote><p> |
| Returns: (basic_filebuf<charT,traits>*)&sb. |
| </p></blockquote> |
| |
| <p>to:</p> |
| <blockquote><p> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </p></blockquote> |
| |
| <p>Change 27.8.1.10/1 from:</p> |
| <blockquote><p> |
| Returns: (basic_filebuf<charT,traits>*)&sb. |
| </p></blockquote> |
| |
| <p>to:</p> |
| <blockquote><p> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </p></blockquote> |
| |
| <p>Change 27.8.1.13/1 from:</p> |
| <blockquote><p> |
| Returns: &sb. |
| </p></blockquote> |
| |
| <p>to:</p> |
| <blockquote><p> |
| Returns: const_cast<basic_filebuf<charT,traits>*>(&sb). |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="445"></a>445. iterator_traits::reference unspecified for some iterator categories</h3> |
| <p><b>Section:</b> 24.3.1 [iterator.traits] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2003-12-09</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The standard places no restrictions at all on the reference type |
| of input, output, or forward iterators (for forward iterators it |
| only specifies that *x must be value_type& and doesn't mention |
| the reference type). Bidirectional iterators' reference type is |
| restricted only by implication, since the base iterator's |
| reference type is used as the return type of reverse_iterator's |
| operator*, which must be T& in order to be a conforming forward |
| iterator. |
| </p> |
| |
| <p> |
| Here's what I think we ought to be able to expect from an input |
| or forward iterator's reference type R, where a is an iterator |
| and V is its value_type |
| </p> |
| |
| <ul> |
| <li> |
| *a is convertible to R |
| </li> |
| |
| <li> |
| R is convertible to V |
| </li> |
| |
| <li> |
| static_cast<V>(static_cast<R>(*a)) is equivalent to |
| static_cast<V>(*a) |
| </li> |
| </ul> |
| |
| <p>A mutable forward iterator ought to satisfy, for x of type V:</p> |
| <pre> { R r = *a; r = x; } is equivalent to *a = x; |
| </pre> |
| |
| <p> |
| I think these requirements capture existing container iterators |
| (including vector<bool>'s), but render istream_iterator invalid; |
| its reference type would have to be changed to a constant |
| reference. |
| </p> |
| |
| |
| <p> |
| (Jeremy Siek) During the discussion in Sydney, it was felt that a |
| simpler long term solution for this was needed. The solution proposed |
| was to require <tt>reference</tt> to be the same type as <tt>*a</tt> |
| and <tt>pointer</tt> to be the same type as <tt>a-></tt>. Most |
| iterators in the Standard Library already meet this requirement. Some |
| iterators are output iterators, and do not need to meet the |
| requirement, and others are only specified through the general |
| iterator requirements (which will change with this resolution). The |
| sole case where there is an explicit definition of the reference type |
| that will need to change is <tt>istreambuf_iterator</tt> which returns |
| <tt>charT</tt> from <tt>operator*</tt> but has a reference type of |
| <tt>charT&</tt>. We propose changing the reference type of |
| <tt>istreambuf_iterator</tt> to <tt>charT</tt>. |
| </p> |
| |
| <p>The other option for resolving the issue with <tt>pointer</tt>, |
| mentioned in the note below, is to remove <tt>pointer</tt> |
| altogether. I prefer placing requirements on <tt>pointer</tt> to |
| removing it for two reasons. First, <tt>pointer</tt> will become |
| useful for implementing iterator adaptors and in particular, |
| <tt>reverse_iterator</tt> will become more well defined. Second, |
| removing <tt>pointer</tt> is a rather drastic and publicly-visible |
| action to take.</p> |
| |
| <p>The proposed resolution technically enlarges the requirements for |
| iterators, which means there are existing iterators (such as |
| <tt>istreambuf_iterator</tt>, and potentially some programmer-defined |
| iterators) that will no longer meet the requirements. Will this break |
| existing code? The scenario in which it would is if an algorithm |
| implementation (say in the Standard Library) is changed to rely on |
| <tt>iterator_traits::reference</tt>, and then is used with one of the |
| iterators that do not have an appropriately defined |
| <tt>iterator_traits::reference</tt>. |
| </p> |
| |
| |
| <p>The proposed resolution makes one other subtle change. Previously, |
| it was required that output iterators have a <tt>difference_type</tt> |
| and <tt>value_type</tt> of <tt>void</tt>, which means that a forward |
| iterator could not be an output iterator. This is clearly a mistake, |
| so I've changed the wording to say that those types may be |
| <tt>void</tt>. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>In 24.3.1 [iterator.traits], after:</p> |
| |
| <blockquote><p> |
| be defined as the iterator's difference type, value type and iterator |
| category, respectively. |
| </p></blockquote> |
| |
| <p>add</p> |
| |
| <blockquote><p> |
| In addition, the types</p> |
| <pre>iterator_traits<Iterator>::reference |
| iterator_traits<Iterator>::pointer |
| </pre> |
| <p>must be defined as the iterator's reference and pointer types, that |
| is, the same type as the type of <tt>*a</tt> and <tt>a-></tt>, |
| respectively.</p> |
| </blockquote> |
| |
| <p>In 24.3.1 [iterator.traits], change:</p> |
| |
| <blockquote><p> |
| In the case of an output iterator, the types</p> |
| <pre>iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type |
| </pre> |
| <p>are both defined as <tt>void</tt>.</p> |
| </blockquote> |
| |
| <p>to:</p> |
| <blockquote><p> |
| In the case of an output iterator, the types</p> |
| <pre>iterator_traits<Iterator>::difference_type |
| iterator_traits<Iterator>::value_type |
| iterator_traits<Iterator>::reference |
| iterator_traits<Iterator>::pointer |
| </pre> |
| <p>may be defined as <tt>void</tt>.</p> |
| </blockquote> |
| |
| <p>In 24.5.3 [istreambuf.iterator], change:</p> |
| <blockquote> |
| <pre>typename traits::off_type, charT*, charT&> |
| </pre> |
| </blockquote> |
| <p>to:</p> |
| <blockquote> |
| <pre>typename traits::off_type, charT*, charT> |
| </pre> |
| </blockquote> |
| |
| <p><i>[ |
| Redmond: there was concern in Sydney that this might not be the only place |
| where things were underspecified and needed to be changed. Jeremy |
| reviewed iterators in the standard and confirmed that nothing else |
| needed to be changed. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="448"></a>448. Random Access Iterators over abstract classes</h3> |
| <p><b>Section:</b> 24.1.5 [random.access.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2004-01-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#random.access.iterators">issues</a> in [random.access.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 76, the random access iterator requirement table, says that the |
| return type of a[n] must be "convertible to T". When an iterator's |
| value_type T is an abstract class, nothing is convertible to T. |
| Surely this isn't an intended restriction? |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the return type to "convertible to T const&". |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="449"></a>449. Library Issue 306 Goes Too Far</h3> |
| <p><b>Section:</b> 18.1 [support.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Pete Becker <b>Date:</b> 2004-01-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#support.types">issues</a> in [support.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Original text:</p> |
| <blockquote><p> |
| The macro offsetof accepts a restricted set of type arguments in this |
| International Standard. type shall be a POD structure or a POD union |
| (clause 9). The result of applying the offsetof macro to a field that |
| is a static data member or a function member is undefined." |
| </p></blockquote> |
| |
| <p>Revised text:</p> |
| <blockquote><p> |
| "If type is not a POD structure or a POD union the results are undefined." |
| </p></blockquote> |
| |
| <p> |
| Looks to me like the revised text should have replaced only the second |
| sentence. It doesn't make sense standing alone. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 18.1, paragraph 5, to:</p> |
| |
| <blockquote><p> |
| The macro offsetof accepts a restricted set of type arguments in this |
| International Standard. If type is not a POD structure or a POD union |
| the results are undefined. The result of applying the offsetof macro |
| to a field that is a static data member or a function member is |
| undefined." |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="453"></a>453. basic_stringbuf::seekoff need not always fail for an empty stream</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bill Plauger <b>Date:</b> 2004-01-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <pre> pos_type basic_stringbuf::seekoff(off_type, ios_base::seekdir, |
| ios_base::openmode); |
| </pre> |
| <p> |
| is obliged to fail if nothing has been inserted into the stream. This |
| is unnecessary and undesirable. It should be permissible to seek to |
| an effective offset of zero.</p> |
| |
| <p><i>[ |
| Sydney: Agreed that this is an annoying problem: seeking to zero should be |
| legal. Bill will provide wording. |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change the sentence from:</p> |
| <blockquote><p> |
| For a sequence to be positioned, if its next pointer (either |
| gptr() or pptr()) is a null pointer, the positioning operation |
| fails. |
| </p></blockquote> |
| |
| <p>to:</p> |
| |
| <blockquote><p> |
| For a sequence to be positioned, if its next pointer (either |
| gptr() or pptr()) is a null pointer and the new offset newoff |
| is nonzero, the positioning operation fails. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="455"></a>455. cerr::tie() and wcerr::tie() are overspecified</h3> |
| <p><b>Section:</b> 27.3 [iostream.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Bill Plauger <b>Date:</b> 2004-01-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostream.objects">issues</a> in [iostream.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Both cerr::tie() and wcerr::tie() are obliged to be null at program |
| startup. This is overspecification and overkill. It is both traditional |
| and useful to tie cerr to cout, to ensure that standard output is drained |
| whenever an error message is written. This behavior should at least be |
| permitted if not required. Same for wcerr::tie(). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Add to the description of cerr:</p> |
| <blockquote><p> |
| After the object cerr is initialized, cerr.tie() returns &cout. |
| Its state is otherwise the same as required for basic_ios<char>::init |
| (lib.basic.ios.cons). |
| </p></blockquote> |
| |
| <p>Add to the description of wcerr:</p> |
| |
| <blockquote><p> |
| After the object wcerr is initialized, wcerr.tie() returns &wcout. |
| Its state is otherwise the same as required for basic_ios<wchar_t>::init |
| (lib.basic.ios.cons). |
| </p></blockquote> |
| |
| <p><i>[Sydney: straw poll (3-1): we should <i>require</i>, not just |
| permit, cout and cerr to be tied on startup. Pre-Redmond: Bill will |
| provide wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="456"></a>456. Traditional C header files are overspecified</h3> |
| <p><b>Section:</b> 17.4.1.2 [headers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bill Plauger <b>Date:</b> 2004-01-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#headers">issues</a> in [headers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>The C++ Standard effectively requires that the traditional C headers |
| (of the form <xxx.h>) be defined in terms of the newer C++ |
| headers (of the form <cxxx>). Clauses 17.4.1.2/4 and D.5 combine |
| to require that:</p> |
| |
| <ul> |
| <li>Including the header <cxxx> declares a C name in namespace std.</li> |
| |
| <li> Including the header <xxx.h> declares a C name in namespace std |
| (effectively by including <cxxx>), then imports it into the global |
| namespace with an individual using declaration.</li> |
| </ul> |
| |
| <p> |
| The rules were left in this form despited repeated and heated objections |
| from several compiler vendors. The C headers are often beyond the direct |
| control of C++ implementors. In some organizations, it's all they can do |
| to get a few #ifdef __cplusplus tests added. Third-party library vendors |
| can perhaps wrap the C headers. But neither of these approaches supports |
| the drastic restructuring required by the C++ Standard. As a result, it is |
| still widespread practice to ignore this conformance requirement, nearly |
| seven years after the committee last debated this topic. Instead, what is |
| often implemented is: |
| </p> |
| |
| <ul> |
| <li> Including the header <xxx.h> declares a C name in the |
| global namespace.</li> |
| |
| <li> Including the header <cxxx> declares a C name in the |
| global namespace (effectively by including <xxx.h>), then |
| imports it into namespace std with an individual using declaration.</li> |
| </ul> |
| |
| <p> |
| The practical benefit for implementors with the second approach is that |
| they can use existing C library headers, as they are pretty much obliged |
| to do. The practical cost for programmers facing a mix of implementations |
| is that they have to assume weaker rules:</p> |
| |
| <ul> |
| <li> If you want to assuredly declare a C name in the global |
| namespace, include <xxx.h>. You may or may not also get the |
| declaration in namespace std.</li> |
| |
| <li> If you want to assuredly declare a C name in namespace std, |
| include <cxxx>. You may or may not also get the declaration in |
| the global namespace.</li> |
| </ul> |
| |
| <p> |
| There also exists the <i>possibility</i> of subtle differences due to |
| Koenig lookup, but there are so few non-builtin types defined in the C |
| headers that I've yet to see an example of any real problems in this |
| area. |
| </p> |
| |
| <p> |
| It is worth observing that the rate at which programmers fall afoul of |
| these differences has remained small, at least as measured by newsgroup |
| postings and our own bug reports. (By an overwhelming margin, the |
| commonest problem is still that programmers include <string> and can't |
| understand why the typename string isn't defined -- this a decade after |
| the committee invented namespace std, nominally for the benefit of all |
| programmers.) |
| </p> |
| |
| <p> |
| We should accept the fact that we made a serious mistake and rectify it, |
| however belatedly, by explicitly allowing either of the two schemes for |
| declaring C names in headers. |
| </p> |
| |
| <p><i>[Sydney: This issue has been debated many times, and will |
| certainly have to be discussed in full committee before any action |
| can be taken. However, the preliminary sentiment of the LWG was in |
| favor of the change. (6 yes, 0 no, 2 abstain) Robert Klarer |
| suggests that we might also want to undeprecate the |
| C-style <tt>.h</tt> headers.]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 17.4.1.2 [headers], para. 4: |
| </p> |
| |
| <blockquote><p> |
| Except as noted in clauses 18 through 27 and Annex D, the contents of each |
| header <i>cname</i> shall be the same as that of the corresponding header |
| <i>name.h</i>, as specified in ISO/IEC 9899:1990 Programming Languages C (Clause |
| 7), or ISO/IEC:1990 Programming Languages-C AMENDMENT 1: C Integrity, (Clause |
| 7), as appropriate, as if by inclusion. In the C++ Standard Library, however, |
| the declarations <del>and definitions</del> (except for names which are defined |
| as macros in C) are within namespace scope (3.3.5) of the namespace std. |
| <ins>It is unspecified whether these names are first declared within the global |
| namespace scope and are then injected into namespace std by explicit |
| using-declarations (7.3.3 [namespace.udecl]).</ins> |
| </p></blockquote> |
| |
| <p> |
| Change D.5 [depr.c.headers], para. 2-3: |
| </p> |
| |
| <blockquote> |
| <p> |
| -2- Every C header, each of which has a name of the form <i>name.h</i>, behaves |
| as if each name placed in the Standard library namespace by the corresponding |
| <i>cname</i> header is <del>also</del> placed within the <ins>global</ins> |
| namespace scope<ins>.</ins> <del>of the namespace <tt>std</tt> and is followed |
| by an explicit <i>using-declaration</i> (7.3.3 [namespace.udecl]).</del> |
| <ins>It is unspecified whether these names are first declared or defined within |
| namespace scope (3.3.5 [basic.scope.namespace]) of the namespace |
| <tt>std</tt> and are then injected into the global namespace scope by explicit |
| using-declarations (7.3.3 [namespace.udecl]).</ins> |
| </p> |
| <p> |
| -3- [<i>Example:</i> The header <tt><cstdlib></tt> <ins>assuredly</ins> |
| provides its declarations and definitions within the namespace <tt>std</tt>. |
| <ins>It may also provide these names within the global namespace.</ins> The |
| header <tt><stdlib.h></tt> <del>makes these available also in</del> |
| <ins>assuredly provides the same declarations and definitions within</ins> the |
| global namespace, much as in the C Standard. <ins>It may also provide these |
| names within the namespace <tt>std</tt>.</ins> <i>-- end example</i>] |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="457"></a>457. bitset constructor: incorrect number of initialized bits</h3> |
| <p><b>Section:</b> 23.3.5.1 [bitset.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Dag Henriksson <b>Date:</b> 2004-01-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#bitset.cons">issues</a> in [bitset.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The constructor from unsigned long says it initializes "the first M |
| bit positions to the corresponding bit values in val. M is the smaller |
| of N and the value CHAR_BIT * sizeof(unsigned long)." |
| </p> |
| |
| <p> |
| Object-representation vs. value-representation strikes again. CHAR_BIT * |
| sizeof (unsigned long) does not give us the number of bits an unsigned long |
| uses to hold the value. Thus, the first M bit position above is not |
| guaranteed to have any corresponding bit values in val. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.3.5.1 [bitset.cons] paragraph 2, change "M is the smaller of |
| N and the value CHAR_BIT * sizeof (unsigned long). (249)" to |
| "<tt>M</tt> is the smaller of <tt>N</tt> and the number of bits in |
| the value representation (section 3.9 [basic.types]) of <tt>unsigned |
| long</tt>." |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="460"></a>460. Default modes missing from basic_fstream member specifications</h3> |
| <p><b>Section:</b> 27.8.1 [fstreams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Ben Hutchings <b>Date:</b> 2004-04-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#fstreams">issues</a> in [fstreams].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The second parameters of the non-default constructor and of the open |
| member function for basic_fstream, named "mode", are optional |
| according to the class declaration in 27.8.1.11 [lib.fstream]. The |
| specifications of these members in 27.8.1.12 [lib.fstream.cons] and |
| 27.8.1.13 lib.fstream.members] disagree with this, though the |
| constructor declaration has the "explicit" function-specifier implying |
| that it is intended to be callable with one argument. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 27.8.1.15 [fstream.cons], change</p> |
| <pre> explicit basic_fstream(const char* s, ios_base::openmode mode); |
| </pre> |
| <p>to</p> |
| <pre> explicit basic_fstream(const char* s, |
| ios_base::openmode mode = ios_base::in|ios_base::out); |
| </pre> |
| <p>In 27.8.1.17 [fstream.members], change</p> |
| <pre> void open(const char*s, ios_base::openmode mode); |
| </pre> |
| <p>to</p> |
| <pre> void open(const char*s, |
| ios_base::openmode mode = ios_base::in|ios_base::out); |
| </pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="461"></a>461. time_get hard or impossible to implement</h3> |
| <p><b>Section:</b> 22.2.5.1.2 [locale.time.get.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bill Plauger <b>Date:</b> 2004-03-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Template time_get currently contains difficult, if not impossible, |
| requirements for do_date_order, do_get_time, and do_get_date. All require |
| the implementation to scan a field generated by the %x or %X conversion |
| specifier in strftime. Yes, do_date_order can always return no_order, but |
| that doesn't help the other functions. The problem is that %x can be |
| nearly anything, and it can vary widely with locales. It's horribly |
| onerous to have to parse "third sunday after Michaelmas in the year of |
| our Lord two thousand and three," but that's what we currently ask of |
| do_get_date. More practically, it leads some people to think that if |
| %x produces 10.2.04, we should know to look for dots as separators. Still |
| not easy. |
| </p> |
| |
| <p> |
| Note that this is the <i>opposite</i> effect from the intent stated in the |
| footnote earlier in this subclause: |
| </p> |
| |
| <blockquote><p> |
| "In other words, user confirmation is required for reliable parsing of |
| user-entered dates and times, but machine-generated formats can be |
| parsed reliably. This allows parsers to be aggressive about interpreting |
| user variations on standard formats." |
| </p></blockquote> |
| |
| <p> |
| We should give both implementers and users an easier and more reliable |
| alternative: provide a (short) list of alternative delimiters and say |
| what the default date order is for no_order. For backward compatibility, |
| and maximum latitude, we can permit an implementation to parse whatever |
| %x or %X generates, but we shouldn't require it. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><b>In the description:</b></p> |
| <pre>iter_type do_get_time(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| </pre> |
| |
| <p> |
| 2 Effects: Reads characters starting at suntil it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce the format specified by 'X', or until it |
| encounters an error or end of sequence. |
| </p> |
| |
| <p><b>change:</b> 'X'</p> |
| |
| <p><b>to:</b> "%H:%M:%S"</p> |
| |
| |
| <p>Change</p> |
| <pre>iter_type do_get_date(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| |
| 4 Effects: Reads characters starting at s until it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce the format specified by 'x', or until it |
| encounters an error. |
| </pre> |
| |
| <p>to</p> |
| <pre>iter_type do_get_date(iter_type s, iter_type end, ios_base& str, |
| ios_base::iostate& err, tm* t) const; |
| </pre> |
| |
| <p> |
| 4 Effects: Reads characters starting at s until it has extracted those |
| struct tm members, and remaining format characters, used by |
| time_put<>::put to produce one of the following formats, or until it |
| encounters an error. The format depends on the value returned by |
| date_order() as follows: |
| </p> |
| |
| <pre> date_order() format |
| |
| no_order "%m/%d/%y" |
| dmy "%d/%m/%y" |
| mdy "%m/%d/%y" |
| ymd "%y/%m/%d" |
| ydm "%y/%d/%m" |
| </pre> |
| <p> |
| An implementation may also accept additional implementation-defined formats. |
| </p> |
| |
| <p><i>[Redmond: agreed that this is a real problem. The solution is |
| probably to match C99's parsing rules. Bill provided wording. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="464"></a>464. Suggestion for new member functions in standard containers</h3> |
| <p><b>Section:</b> 23.2.6 [vector], 23.3.1 [map] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thorsten Ottosen <b>Date:</b> 2004-05-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector">issues</a> in [vector].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>To add slightly more convenience to vector<T> and map<Key,T> we should consider to add</p> |
| <ol> |
| <li> add vector<T>::data() member (const and non-const version) |
| semantics: if( empty() ) return 0; else return buffer_;</li> |
| <li> add map<Key,T>::at( const Key& k ) member (const and non-const version) |
| <i>semantics</i>: iterator i = find( k ); if( i != end() ) return *i; else throw range_error();</li> |
| </ol> |
| |
| <p>Rationale:</p> |
| |
| <ul> |
| <li>To obtain a pointer to the vector's buffer, one must use either |
| operator[]() (which can give undefined behavior for empty vectors) or |
| at() (which will then throw if the vector is empty). </li> |
| <li>tr1::array<T,sz> already has a data() member</li> |
| <li>e cannot use operator[]() when T is not DefaultDonstructible</li> |
| <li>Neither when the map is const.</li> |
| <li>when we want to make sure we don't add an element accidently</li> |
| <li>when it should be considered an error if a key is not in the map</li> |
| </ul> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 23.2.6 [vector], add the following to the <tt>vector</tt> |
| synopsis after "element access" and before "modifiers":</p> |
| <pre> // <i>[lib.vector.data] data access</i> |
| pointer data(); |
| const_pointer data() const; |
| </pre> |
| |
| <p>Add a new subsection of 23.2.6 [vector]:</p> |
| <blockquote> |
| <p>23.2.4.x <tt>vector</tt> data access</p> |
| <pre> pointer data(); |
| const_pointer data() const; |
| </pre> |
| <p><b>Returns:</b> A pointer such that [data(), data() + size()) is a valid |
| range. For a non-empty vector, data() == &front().</p> |
| <p><b>Complexity:</b> Constant time.</p> |
| <p><b>Throws:</b> Nothing.</p> |
| </blockquote> |
| |
| <p>In 23.3.1 [map], add the following to the <tt>map</tt> |
| synopsis immediately after the line for operator[]:</p> |
| <pre> T& at(const key_type& x); |
| const T& at(const key_type& x) const; |
| </pre> |
| |
| <p>Add the following to 23.3.1.2 [map.access]:</p> |
| <blockquote> |
| <pre> T& at(const key_type& x); |
| const T& at(const key_type& x) const; |
| </pre> |
| |
| <p><b>Returns:</b> A reference to the element whose key is equivalent |
| to x, if such an element is present in the map.</p> |
| <p><b>Throws:</b> <tt>out_of_range</tt> if no such element is present.</p> |
| |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>Neither of these additions provides any new functionality but the |
| LWG agreed that they are convenient, especially for novices. The |
| exception type chosen for <tt>at</tt>, <tt>std::out_of_range</tt>, |
| was chosen to match <tt>vector::at</tt>.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="465"></a>465. Contents of <ciso646></h3> |
| <p><b>Section:</b> 17.4.1.2 [headers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve Clamage <b>Date:</b> 2004-06-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#headers">issues</a> in [headers].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>C header <iso646.h> defines macros for some operators, such as |
| not_eq for !=.</p> |
| |
| <p>Section 17.4.1.2 [headers] "Headers" says that except as noted in |
| clauses 18 through 27, the <cname> C++ header contents are the same |
| as the C header <name.h>. In particular, table 12 lists |
| <ciso646> as a C++ header.</p> |
| |
| <p>I don't find any other mention of <ciso646>, or any mention of |
| <iso646.h>, in clauses 17 thorough 27. That implies that the |
| contents of <ciso646> are the same as C header <iso646.h>.</p> |
| |
| <p>Annex C (informative, not normative) in [diff.header.iso646.h] C.2.2.2 |
| "Header <iso646.h>" says that the alternative tokens are not |
| defined as macros in <ciso646>, but does not mention the contents |
| of <iso646.h>.</p> |
| |
| <p>I don't find any normative text to support C.2.2.2.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add to section 17.4.1.2 Headers [lib.headers] a new paragraph after |
| paragraph 6 (the one about functions must be functions):</p> |
| |
| <blockquote> |
| <p>Identifiers that are keywords or operators in C++ shall not be defined |
| as macros in C++ standard library headers. |
| [Footnote:In particular, including the standard header <iso646.h> |
| or <ciso646> has no effect. </p> |
| </blockquote> |
| |
| <p><i>[post-Redmond: Steve provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="467"></a>467. char_traits::lt(), compare(), and memcmp()</h3> |
| <p><b>Section:</b> 21.1.3.1 [char.traits.specializations.char] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2004-06-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| Table 37 describes the requirements on Traits::compare() in terms of |
| those on Traits::lt(). 21.1.3.1, p6 requires char_traits<char>::lt() |
| to yield the same result as operator<(char, char). |
| </p> |
| |
| <p> |
| Most, if not all, implementations of char_traits<char>::compare() |
| call memcmp() for efficiency. However, the C standard requires both |
| memcmp() and strcmp() to interpret characters under comparison as |
| unsigned, regardless of the signedness of char. As a result, all |
| these char_traits implementations fail to meet the requirement |
| imposed by Table 37 on compare() when char is signed. |
| </p> |
| |
| |
| <p>Read email thread starting with c++std-lib-13499 for more. </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| |
| <p>Change 21.1.3.1, p6 from</p> |
| <blockquote><p> |
| The two-argument members assign, eq, and lt are defined identically |
| to the built-in operators =, ==, and < respectively. |
| </p></blockquote> |
| <p>to</p> |
| <blockquote><p> |
| The two-argument member assign is defined identically to |
| the built-in operator =. The two |
| argument members eq and lt are defined identically to |
| the built-in operators == and < for type unsigned char. |
| </p></blockquote> |
| |
| <p><i>[Redmond: The LWG agreed with this general direction, but we |
| also need to change <tt>eq</tt> to be consistent with this change. |
| Post-Redmond: Martin provided wording.]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="468"></a>468. unexpected consequences of ios_base::operator void*()</h3> |
| <p><b>Section:</b> 27.4.4.3 [iostate.flags] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2004-06-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostate.flags">issues</a> in [iostate.flags].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>The program below is required to compile but when run it typically |
| produces unexpected results due to the user-defined conversion from |
| std::cout or any object derived from basic_ios to void*. |
| </p> |
| |
| <pre> #include <cassert> |
| #include <iostream> |
| |
| int main () |
| { |
| assert (std::cin.tie () == std::cout); |
| // calls std::cout.ios::operator void*() |
| } |
| </pre> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Replace std::basic_ios<charT, traits>::operator void*() with another |
| conversion operator to some unspecified type that is guaranteed not |
| to be convertible to any other type except for bool (a pointer-to-member |
| might be one such suitable type). In addition, make it clear that the |
| pointer type need not be a pointer to a complete type and when non-null, |
| the value need not be valid. |
| </p> |
| |
| <p>Specifically, change in [lib.ios] the signature of</p> |
| <pre> operator void*() const; |
| </pre> |
| <p>to</p> |
| <pre> operator unspecified-bool-type() const; |
| </pre> |
| <p>and change [lib.iostate.flags], p1 from</p> |
| <pre> operator void*() const; |
| </pre> |
| <p>to</p> |
| <pre>operator unspecified-bool-type() const; |
| |
| -1- Returns: if fail() then a value that will evaluate false in a |
| boolean context; otherwise a value that will evaluate true in a |
| boolean context. The value type returned shall not be |
| convertible to int. |
| |
| -2- [Note: This conversion can be used in contexts where a bool |
| is expected (e.g., an if condition); however, implicit |
| conversions (e.g., to int) that can occur with bool are not |
| allowed, eliminating some sources of user error. One possible |
| implementation choice for this type is pointer-to-member. - end |
| note] |
| </pre> |
| |
| <p><i>[Redmond: 5-4 straw poll in favor of doing this.]</i></p> |
| |
| <p><i>[Lillehammer: Doug provided revised wording for |
| "unspecified-bool-type".]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="469"></a>469. vector<bool> ill-formed relational operators</h3> |
| <p><b>Section:</b> 23.2.6 [vector] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2004-06-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector">issues</a> in [vector].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| The overloads of relational operators for vector<bool> specified |
| in [lib.vector.bool] are redundant (they are semantically identical |
| to those provided for the vector primary template) and may even be |
| diagnosed as ill-formed (refer to Daveed Vandevoorde's explanation |
| in c++std-lib-13647). |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove all overloads of overloads of relational operators for |
| vector<bool> from [lib.vector.bool]. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="474"></a>474. confusing Footnote 297</h3> |
| <p><b>Section:</b> 27.6.2.6.4 [ostream.inserters.character] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2004-07-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.inserters.character">issues</a> in [ostream.inserters.character].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| I think Footnote 297 is confused. The paragraph it applies to seems |
| quite clear in that widen() is only called if the object is not a char |
| stream (i.e., not basic_ostream<char>), so it's irrelevant what the |
| value of widen(c) is otherwise. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I propose to strike the Footnote. |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="475"></a>475. May the function object passed to for_each modify the elements of the iterated sequence?</h3> |
| <p><b>Section:</b> 25.1.4 [alg.foreach] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Stephan T. Lavavej, Jaakko Jarvi <b>Date:</b> 2004-07-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.foreach">issues</a> in [alg.foreach].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It is not clear whether the function object passed to for_each is allowed to |
| modify the elements of the sequence being iterated over. |
| </p> |
| |
| <p> |
| for_each is classified without explanation in [lib.alg.nonmodifying], "25.1 |
| Non-modifying sequence operations". 'Non-modifying sequence operation' is |
| never defined. |
| </p> |
| |
| <p> |
| 25(5) says: "If an algorithm's Effects section says that a value pointed to |
| by any iterator passed as an argument is modified, then that algorithm has |
| an additional type requirement: The type of that argument shall satisfy the |
| requirements of a mutable iterator (24.1)." |
| </p> |
| |
| <p>for_each's Effects section does not mention whether arguments can be |
| modified:</p> |
| |
| <blockquote><p> |
| "Effects: Applies f to the result of dereferencing every iterator in the |
| range [first, last), starting from first and proceeding to last - 1." |
| </p></blockquote> |
| |
| <p> |
| Every other algorithm in [lib.alg.nonmodifying] is "really" non-modifying in |
| the sense that neither the algorithms themselves nor the function objects |
| passed to the algorithms may modify the sequences or elements in any way. |
| This DR affects only for_each. |
| </p> |
| |
| <p> |
| We suspect that for_each's classification in "non-modifying sequence |
| operations" means that the algorithm itself does not inherently modify the |
| sequence or the elements in the sequence, but that the function object |
| passed to it may modify the elements it operates on. |
| </p> |
| |
| <p> |
| The original STL document by Stepanov and Lee explicitly prohibited the |
| function object from modifying its argument. |
| The "obvious" implementation of for_each found in several standard library |
| implementations, however, does not impose this restriction. |
| As a result, we suspect that the use of for_each with function objects that modify |
| their arguments is wide-spread. |
| If the restriction was reinstated, all such code would become non-conforming. |
| Further, none of the other algorithms in the Standard |
| could serve the purpose of for_each (transform does not guarantee the order in |
| which its function object is called). |
| </p> |
| |
| <p> |
| We suggest that the standard be clarified to explicitly allow the function object |
| passed to for_each modify its argument.</p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add a nonnormative note to the Effects in 25.1.4 [alg.foreach]: If |
| the type of 'first' satisfies the requirements of a mutable iterator, |
| 'f' may apply nonconstant functions through the dereferenced iterators |
| passed to it. |
| </p> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p>The LWG believes that nothing in the standard prohibits function |
| objects that modify the sequence elements. The problem is that |
| for_each is in a secion entitled "nonmutating algorithms", and the |
| title may be confusing. A nonnormative note should clarify that.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="478"></a>478. Should forward iterator requirements table have a line for r->m?</h3> |
| <p><b>Section:</b> 24.1.3 [forward.iterators] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Dave Abrahams <b>Date:</b> 2004-07-11</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#forward.iterators">issues</a> in [forward.iterators].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#477">477</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The Forward Iterator requirements table contains the following: |
| </p> |
| <pre> expression return type operational precondition |
| semantics |
| ========== ================== =========== ========================== |
| a->m U& if X is mutable, (*a).m pre: (*a).m is well-defined. |
| otherwise const U& |
| |
| r->m U& (*r).m pre: (*r).m is well-defined. |
| </pre> |
| |
| <p>The second line may be unnecessary. Paragraph 11 of |
| [lib.iterator.requirements] says: |
| </p> |
| |
| <blockquote><p> |
| In the following sections, a and b denote values of type const X, n |
| denotes a value of the difference type Distance, u, tmp, and m |
| denote identifiers, r denotes a value of X&, t denotes a value of |
| value type T, o denotes a value of some type that is writable to |
| the output iterator. |
| </p></blockquote> |
| |
| <p> |
| Because operators can be overloaded on an iterator's const-ness, the |
| current requirements allow iterators to make many of the operations |
| specified using the identifiers a and b invalid for non-const |
| iterators.</p> |
| |
| <p>Related issue: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#477">477</a></p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p>Remove the "r->m" line from the Forward Iterator requirements |
| table. Change</p> |
| <blockquote><p> |
| "const X" |
| </p></blockquote> |
| |
| <p> to </p> |
| |
| <blockquote><p> |
| "X or const X" |
| </p></blockquote> |
| |
| <p>in paragraph 11 of [lib.iterator.requirements].</p> |
| |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| This is a defect because it constrains an lvalue to returning a modifiable lvalue. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="488"></a>488. rotate throws away useful information</h3> |
| <p><b>Section:</b> 25.2.11 [alg.rotate] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2004-11-22</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| rotate takes 3 iterators: first, middle and last which point into a |
| sequence, and rearranges the sequence such that the subrange [middle, |
| last) is now at the beginning of the sequence and the subrange [first, |
| middle) follows. The return type is void. |
| </p> |
| |
| <p> |
| In many use cases of rotate, the client needs to know where the |
| subrange [first, middle) starts after the rotate is performed. This |
| might look like: |
| </p> |
| <pre> rotate(first, middle, last); |
| Iterator i = advance(first, distance(middle, last)); |
| </pre> |
| |
| <p> |
| Unless the iterators are random access, the computation to find the |
| start of the subrange [first, middle) has linear complexity. However, |
| it is not difficult for rotate to return this information with |
| negligible additional computation expense. So the client could code: |
| </p> |
| <pre> Iterator i = rotate(first, middle, last); |
| </pre> |
| |
| <p> |
| and the resulting program becomes significantly more efficient. |
| </p> |
| |
| <p> |
| While the backwards compatibility hit with this change is not zero, it |
| is very small (similar to that of lwg <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#130">130</a>), and there is |
| a significant benefit to the change. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>In 25 [algorithms] p2, change:</p> |
| |
| <blockquote><pre> template<class ForwardIterator> |
| <del>void</del> <ins>ForwardIterator</ins> rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre></blockquote> |
| |
| <p>In 25.2.11 [alg.rotate], change:</p> |
| |
| <blockquote><pre> template<class ForwardIterator> |
| <del>void</del> <ins>ForwardIterator</ins> rotate(ForwardIterator first, ForwardIterator middle, |
| ForwardIterator last); |
| </pre></blockquote> |
| |
| <p>In 25.2.11 [alg.rotate] insert a new paragraph after p1:</p> |
| |
| <blockquote> |
| <p><b>Returns</b>: <tt>first + (last - middle)</tt>.</p> |
| </blockquote> |
| |
| <p><i>[ |
| The LWG agrees with this idea, but has one quibble: we want to make |
| sure not to give the impression that the function "advance" is |
| actually called, just that the nth iterator is returned. (Calling |
| advance is observable behavior, since users can specialize it for |
| their own iterators.) Howard will provide wording. |
| ]</i></p> |
| |
| |
| <p><i>[Howard provided wording for mid-meeting-mailing Jun. 2005.]</i></p> |
| |
| |
| <p><i>[ |
| Toronto: moved to Ready. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="495"></a>495. Clause 22 template parameter requirements</h3> |
| <p><b>Section:</b> 22 [localization] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2005-01-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#localization">issues</a> in [localization].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>It appears that there are no requirements specified for many of the |
| template parameters in clause 22. It looks like this issue has never |
| come up, except perhaps for Facet.</p> |
| |
| <p>Clause 22 isn't even listed in 17.3.2.1 [lib.type.descriptions], |
| either, which is the wording that allows requirements on template |
| parameters to be identified by name.</p> |
| |
| <p>So one issue is that 17.3.2.1 [lib.type.descriptions] Should be |
| changed to cover clause 22. A better change, which will cover us in |
| the future, would be to say that it applies to all the library |
| clauses. Then if a template gets added to any library clause we are |
| covered.</p> |
| |
| <p>charT, InputIterator, and other names with requirements defined |
| elsewhere are fine, assuming the 17.3.2.1 [lib.type.descriptions] fix. |
| But there are a few template arguments names which I don't think have |
| requirements given elsewhere:</p> |
| |
| <ul> |
| <li>internT and externT. The fix is to add wording saying that internT |
| and externT must meet the same requirements as template arguments |
| named charT.</li> |
| |
| <li>stateT. I'm not sure about this one. There already is some wording, |
| but it seems a bit vague.</li> |
| |
| <li>Intl. [lib.locale.moneypunct.byname] The fix for this one is to |
| rename "Intl" to "International". The name is important because other |
| text identifies the requirements for the name International but not |
| for Intl.</li> |
| </ul> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change 17.3.2.1 [type.descriptions], paragraph 1, from:</p> |
| <blockquote><p> |
| The Requirements subclauses may describe names that are used to |
| specify constraints on template arguments.153) These names are used in |
| clauses 20, 23, 25, and 26 to describe the types that may be supplied |
| as arguments by a C++ program when instantiating template components |
| from the library. |
| </p></blockquote> |
| <p>to:</p> |
| <blockquote><p> |
| The Requirements subclauses may describe names that are used to |
| specify constraints on template arguments.153) These names are used in |
| library clauses to describe the types that may be supplied as |
| arguments by a C++ program when instantiating template components from |
| the library. |
| </p></blockquote> |
| |
| <p>In the front matter of class 22, locales, add:</p> |
| <blockquote><p> |
| Template parameter types internT and externT shall meet the |
| requirements of charT (described in 21 [strings]). |
| </p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Again, a blanket clause isn't blanket enough. Also, we've got a |
| couple of names that we don't have blanket requirement statements |
| for. The only issue is what to do about stateT. This wording is |
| thin, but probably adequate.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="496"></a>496. Illegal use of "T" in vector<bool></h3> |
| <p><b>Section:</b> 23.2.6 [vector] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> richard@ex-parrot.com <b>Date:</b> 2005-02-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector">issues</a> in [vector].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the synopsis of the std::vector<bool> specialisation in 23.2.6 [vector], |
| the non-template assign() function has the signature</p> |
| |
| <pre> void assign( size_type n, const T& t ); |
| </pre> |
| |
| <p>The type, T, is not defined in this context.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Replace "T" with "value_type".</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="497"></a>497. meaning of numeric_limits::traps for floating point types</h3> |
| <p><b>Section:</b> 18.2.1.2 [numeric.limits.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2005-03-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#numeric.limits.members">issues</a> in [numeric.limits.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p>18.2.1.2, p59 says this much about the traps member of numeric_limits:</p> |
| |
| <blockquote> |
| <p>static const bool traps;<br> |
| -59- true if trapping is implemented for the type.204) |
| <br> |
| Footnote 204: Required by LIA-1. |
| </p> |
| </blockquote> |
| |
| <p>It's not clear what is meant by "is implemented" here.</p> |
| |
| <p> |
| In the context of floating point numbers it seems reasonable to expect |
| to be able to use traps to determine whether a program can "safely" use |
| infinity(), quiet_NaN(), etc., in arithmetic expressions, that is |
| without causing a trap (i.e., on UNIX without having to worry about |
| getting a signal). When traps is true, I would expect any of the |
| operations in section 7 of IEEE 754 to cause a trap (and my program |
| to get a SIGFPE). So, for example, on Alpha, I would expect traps |
| to be true by default (unless I compiled my program with the -ieee |
| option), false by default on most other popular architectures, |
| including IA64, MIPS, PA-RISC, PPC, SPARC, and x86 which require |
| traps to be explicitly enabled by the program. |
| </p> |
| |
| <p> |
| Another possible interpretation of p59 is that traps should be true |
| on any implementation that supports traps regardless of whether they |
| are enabled by default or not. I don't think such an interpretation |
| makes the traps member very useful, even though that is how traps is |
| implemented on several platforms. It is also the only way to implement |
| traps on platforms that allow programs to enable and disable trapping |
| at runtime. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Change p59 to read:</p> |
| <blockquote><p>True if, at program startup, there exists a value of the type that |
| would cause an arithmetic operation using that value to trap.</p></blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Real issue, since trapping can be turned on and off. Unclear what a |
| static query can say about a dynamic issue. The real advice we should |
| give users is to use cfenv for these sorts of queries. But this new |
| proposed resolution is at least consistent and slightly better than |
| nothing.</p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="505"></a>505. Result_type in random distribution requirements</h3> |
| <p><b>Section:</b> 26.4.1 [rand.req], TR1 5.1.1 [tr.rand.req] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown <b>Date:</b> 2005-07-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.req">issues</a> in [rand.req].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 17: Random distribution requirements |
| </p> |
| <p> |
| Row 1 requires that each random distribution provide a nested type "input_type"; |
| this type denotes the type of the values that the distribution consumes. |
| </p> |
| <p> |
| Inspection of all distributions in [tr.rand.dist] reveals that each distribution |
| provides a second typedef ("result_type") that denotes the type of the values the |
| distribution produces when called. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| It seems to me that this is also a requirement |
| for all distributions and should therefore be indicated as such via a new second |
| row to this table 17: |
| </p> |
| <table border="1" cellpadding="5"> |
| <tbody><tr><td>X::result_type</td><td>T</td><td>---</td><td>compile-time</td></tr> |
| </tbody></table> |
| |
| <p><i>[ |
| Berlin: Voted to WP. N1932 adopts the proposed resolution: see Table 5 row 1. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="507"></a>507. Missing requirement for variate_generator::operator()</h3> |
| <p><b>Section:</b> 26.4 [rand], TR1 5.1.3 [tr.rand.var] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown <b>Date:</b> 2005-07-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand">issues</a> in [rand].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Paragraph 11 of [tr.rand.var] equires that the member template |
| </p> |
| <blockquote><pre>template<class T> result_type operator() (T value); |
| </pre></blockquote> |
| <p> |
| return |
| </p> |
| <blockquote><pre>distribution()(e, value) |
| </pre></blockquote> |
| <p> |
| However, not all distributions have an operator() with a corresponding signature. |
| </p> |
| |
| <p><i>[ |
| Berlin: As a working group we voted in favor of N1932 which makes this moot: |
| variate_generator has been eliminated. Then in full committee we voted to give |
| this issue WP status (mistakenly). |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| We therefore recommend that we insert the following precondition before paragraph 11: |
| </p> |
| <blockquote><p> |
| Precondition: <tt>distribution().operator()(e,value)</tt> is well-formed. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="508"></a>508. Bad parameters for ranlux64_base_01</h3> |
| <p><b>Section:</b> 26.4.5 [rand.predef], TR1 5.1.5 [tr.rand.predef] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown <b>Date:</b> 2005-07-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.predef">issues</a> in [rand.predef].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The fifth of these engines with predefined parameters, ranlux64_base_01, |
| appears to have an unintentional error for which there is a simple correction. |
| The two pre-defined subtract_with_carry_01 engines are given as: |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<float, 24, 10, 24> ranlux_base_01; |
| typedef subtract_with_carry_01<double, 48, 10, 24> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| We demonstrate below that ranlux64_base_01 fails to meet the intent of the |
| random number generation proposal, but that the simple correction to |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| does meet the intent of defining well-known good parameterizations. |
| </p> |
| <p> |
| The ranlux64_base_01 engine as presented fails to meet the intent for |
| predefined engines, stated in proposal N1398 (section E): |
| </p> |
| <blockquote><p> |
| In order to make good random numbers available to a large number of library |
| users, this proposal not only defines generic random-number engines, but also |
| provides a number of predefined well-known good parameterizations for those. |
| </p></blockquote> |
| <p> |
| The predefined ranlux_base_01 engine has been proven [1,2,3] to have a very |
| long period and so meets this criterion. This property makes it suitable for |
| use in the excellent discard_block engines defined subsequently. The proof |
| of long period relies on the fact (proven in [1]) that 2**(w*r) - 2**(w*s) |
| + 1 is prime (w, r, and s are template parameters to subtract_with_carry_01, |
| as defined in [tr.rand.eng.sub1]). |
| </p> |
| <p> |
| The ranlux64_base_01 engine as presented in [tr.rand.predef] uses w=48, r=24, s=10. |
| For these numbers, the combination 2**(w*r)-2**(w*s)+1 is non-prime (though |
| explicit factorization would be a challenge). In consequence, while it is |
| certainly possible for some seeding states that this engine would have a very |
| long period, it is not at all "well-known" that this is the case. The intent |
| in the N1398 proposal involved the base of the ranlux64 engine, which finds heavy |
| use in the physics community. This is isomorphic to the predefined ranlux_base_01, |
| but exploits the ability of double variables to hold (at least) 48 bits of mantissa, |
| to deliver 48 random bits at a time rather than 24. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To achieve this intended behavior, the correct template parameteriztion would be: |
| </p> |
| <blockquote><pre>typedef subtract_with_carry_01<double, 48, 5, 12> ranlux64_base_01; |
| </pre></blockquote> |
| <p> |
| The sequence of mantissa bits delivered by this is isomorphic (treating each |
| double as having the bits of two floats) to that delivered by ranlux_base_01. |
| </p> |
| <p> |
| <b>References:</b> |
| </p> |
| <ol> |
| <li>F. James, Comput. Phys. Commun. 60(1990) 329</li> |
| <li>G. Marsaglia and A. Zaman, Ann. Appl. Prob 1(1991) 462</li> |
| <li>M. Luscher, Comput. Phys. Commun. 79(1994) 100-110</li> |
| </ol> |
| |
| <p><i>[ |
| Berlin: Voted to WP. N1932 adopts the proposed resolution in 26.3.5, |
| just above paragraph 5. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="518"></a>518. Are insert and erase stable for unordered_multiset and unordered_multimap?</h3> |
| <p><b>Section:</b> 23.1.5 [unord.req], TR1 6.3.1 [tr.unord.req] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2005-07-03</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#unord.req">active issues</a> in [unord.req].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#unord.req">issues</a> in [unord.req].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Issue 371 deals with stability of multiset/multimap under insert and erase |
| (i.e. do they preserve the relative order in ranges of equal elements). |
| The same issue applies to unordered_multiset and unordered_multimap. |
| </p> |
| <p><i>[ |
| Moved to open (from review): There is no resolution. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Toronto: We have a resolution now. Moved to Review. Some concern was noted |
| as to whether this conflicted with existing practice or not. An additional |
| concern was in specifying (partial) ordering for an unordered container. |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Wording for the proposed resolution is taken from the equivalent text for associative containers. |
| </p> |
| |
| <p> |
| Change 23.1.5 [unord.req], Unordered associative containers, paragraph 6 to: |
| </p> |
| |
| <blockquote><p> |
| An unordered associative container supports <i>unique</i> keys if it may |
| contain at most one element for each key. Otherwise, it supports <i>equivalent |
| keys</i>. <tt>unordered_set</tt> and <tt>unordered_map</tt> support |
| unique keys. <tt>unordered_multiset</tt> and <tt>unordered_multimap</tt> |
| support equivalent keys. In containers that support equivalent keys, elements |
| with equivalent keys are adjacent to each other. <ins>For |
| <tt>unordered_multiset</tt> |
| and <tt>unordered_multimap</tt>,<tt> insert</tt> and <tt>erase</tt> |
| preserve the relative ordering of equivalent elements.</ins> |
| </p></blockquote> |
| |
| <p> |
| Change 23.1.5 [unord.req], Unordered associative containers, paragraph 8 to: |
| </p> |
| |
| <blockquote> |
| <p>The elements of an unordered associative container are organized into <i> |
| buckets</i>. Keys with the same hash code appear in the same bucket. The number |
| of buckets is automatically increased as elements are added to an unordered |
| associative container, so that the average number of elements per bucket is kept |
| below a bound. Rehashing invalidates iterators, changes ordering between |
| elements, and changes which buckets elements appear in, but does not invalidate |
| pointers or references to elements. <ins>For <tt>unordered_multiset</tt> |
| and <tt>unordered_multimap</tt>, rehashing |
| preserves the relative ordering of equivalent elements.</ins></p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="519"></a>519. Data() undocumented</h3> |
| <p><b>Section:</b> 23.2.1 [array], TR1 6.2.2 [tr.array.array] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Pete Becker <b>Date:</b> 2005-07-03</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#array">active issues</a> in [array].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#array">issues</a> in [array].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>array<>::data()</tt> is present in the class synopsis, but not documented. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a new section, after 6.2.2.3: |
| </p> |
| <blockquote><pre>T* data() |
| const T* data() const; |
| </pre></blockquote> |
| <p> |
| <b>Returns:</b> <tt>elems</tt>. |
| </p> |
| <p> |
| Change 6.2.2.4/2 to: |
| </p> |
| <blockquote><p> |
| In the case where <tt>N == 0</tt>, <tt>begin() == end()</tt>. The return value |
| of <tt>data()</tt> is unspecified. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="520"></a>520. Result_of and pointers to data members</h3> |
| <p><b>Section:</b> 20.6.11.1 [func.bind], TR1 3.6 [tr.func.bind] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Pete Becker <b>Date:</b> 2005-07-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the original proposal for binders, the return type of bind() when |
| called with a pointer to member data as it's callable object was |
| defined to be mem_fn(ptr); when Peter Dimov and I unified the |
| descriptions of the TR1 function objects we hoisted the descriptions |
| of return types into the INVOKE pseudo-function and into result_of. |
| Unfortunately, we left pointer to member data out of result_of, so |
| bind doesn't have any specified behavior when called with a pointer |
| to member data. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p><i>[ |
| Pete and Peter will provide wording. |
| ]</i></p> |
| |
| |
| <p> |
| In 20.5.4 [lib.func.ret] ([tr.func.ret]) p3 add the following bullet after bullet 2: |
| </p> |
| <ol start="3"> |
| <li>If <tt>F</tt> is a member data pointer type <tt>R T::*</tt>, <tt>type</tt> |
| shall be <tt><i>cv</i> R&</tt> when <tt>T1</tt> is <tt><i>cv</i> U1&</tt>, |
| <tt>R</tt> otherwise.</li> |
| </ol> |
| |
| <p><i>[ |
| Peter provided wording. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="521"></a>521. Garbled requirements for argument_type in reference_wrapper</h3> |
| <p><b>Section:</b> 20.6.5 [refwrap], TR1 2.1.2 [tr.util.refwrp.refwrp] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Pete Becker <b>Date:</b> 2005-07-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 2.1.2/3, second bullet item currently says that reference_wrapper<T> is |
| derived from unary_function<T, R> if T is: |
| </p> |
| <blockquote><p> |
| a pointer to member function type with cv-qualifier cv and no arguments; |
| the type T1 is cv T* and R is the return type of the pointer to member function; |
| </p></blockquote> |
| <p> |
| The type of T1 can't be cv T*, 'cause that's a pointer to a pointer to member |
| function. It should be a pointer to the class that T is a pointer to member of. |
| Like this: |
| </p> |
| <blockquote><p> |
| a pointer to a member function R T0::f() cv (where cv represents the member |
| function's cv-qualifiers); the type T1 is cv T0* |
| </p></blockquote> |
| <p> |
| Similarly, bullet item 2 in 2.1.2/4 should be: |
| </p> |
| <blockquote><p> |
| a pointer to a member function R T0::f(T2) cv (where cv represents the member |
| function's cv-qualifiers); the type T1 is cv T0* |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change bullet item 2 in 2.1.2/3: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li> |
| a pointer to member function <del>type with cv-qualifier <tt><i>cv</i></tt> and no arguments; |
| the type <tt>T1</tt> is <tt><i>cv</i> T*</tt> and <tt>R</tt> is the return |
| type of the pointer to member function</del> <ins><tt>R T0::f() <i>cv</i></tt> |
| (where <tt><i>cv</i></tt> represents the member function's cv-qualifiers); |
| the type <tt>T1</tt> is <tt><i>cv</i> T0*</tt></ins> |
| </li> |
| </ul> |
| </blockquote> |
| |
| <p> |
| Change bullet item 2 in 2.1.2/4: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li> |
| a pointer to member function <del>with cv-qualifier <tt><i>cv</i></tt> and taking one argument |
| of type <tt>T2</tt>; the type <tt>T1</tt> is <tt><i>cv</i> T*</tt> and |
| <tt>R</tt> is the return type of the pointer to member function</del> |
| <ins><tt>R T0::f(T2) <i>cv</i></tt> (where <tt><i>cv</i></tt> represents the member |
| function's cv-qualifiers); the type <tt>T1</tt> is <tt><i>cv</i> T0*</tt></ins> |
| </li> |
| </ul> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="524"></a>524. regex named character classes and case-insensitivity don't mix</h3> |
| <p><b>Section:</b> 28 [re] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Eric Niebler <b>Date:</b> 2005-07-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#re">issues</a> in [re].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| This defect is also being discussed on the Boost developers list. The |
| full discussion can be found here: |
| http://lists.boost.org/boost/2005/07/29546.php |
| </p> |
| <p> |
| -- Begin original message -- |
| </p> |
| <p> |
| Also, I may have found another issue, closely related to the one under |
| discussion. It regards case-insensitive matching of named character |
| classes. The regex_traits<> provides two functions for working with |
| named char classes: lookup_classname and isctype. To match a char class |
| such as [[:alpha:]], you pass "alpha" to lookup_classname and get a |
| bitmask. Later, you pass a char and the bitmask to isctype and get a |
| bool yes/no answer. |
| </p> |
| <p> |
| But how does case-insensitivity work in this scenario? Suppose we're |
| doing a case-insensitive match on [[:lower:]]. It should behave as if it |
| were [[:lower:][:upper:]], right? But there doesn't seem to be enough |
| smarts in the regex_traits interface to do this. |
| </p> |
| <p> |
| Imagine I write a traits class which recognizes [[:fubar:]], and the |
| "fubar" char class happens to be case-sensitive. How is the regex engine |
| to know that? And how should it do a case-insensitive match of a |
| character against the [[:fubar:]] char class? John, can you confirm this |
| is a legitimate problem? |
| </p> |
| <p> |
| I see two options: |
| </p> |
| <p> |
| 1) Add a bool icase parameter to lookup_classname. Then, |
| lookup_classname( "upper", true ) will know to return lower|upper |
| instead of just upper. |
| </p> |
| <p> |
| 2) Add a isctype_nocase function |
| </p> |
| <p> |
| I prefer (1) because the extra computation happens at the time the |
| pattern is compiled rather than when it is executed. |
| </p> |
| <p> |
| -- End original message -- |
| </p> |
| |
| <p> |
| For what it's worth, John has also expressed his preference for option |
| (1) above. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2409.pdf">N2409</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="527"></a>527. tr1::bind has lost its Throws clause</h3> |
| <p><b>Section:</b> 20.6.11.1.3 [func.bind.bind], TR1 3.6.3 [tr.func.bind.bind] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2005-10-01</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#func.bind.bind">active issues</a> in [func.bind.bind].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#func.bind.bind">issues</a> in [func.bind.bind].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The original bind proposal gives the guarantee that tr1::bind(f, t1, |
| ..., tN) does not throw when the copy constructors of f, t1, ..., tN |
| don't. |
| </p> |
| |
| <p> |
| This guarantee is not present in the final version of TR1. |
| </p> |
| |
| <p> |
| I'm pretty certain that we never removed it on purpose. Editorial omission? :-) |
| </p> |
| |
| <p><i>[ |
| Berlin: not quite editorial, needs proposed wording. |
| ]</i></p> |
| |
| <p><i>[ |
| Batavia: Doug to translate wording to variadic templates. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Toronto: We agree but aren't quite happy with the wording. The "t"'s no |
| longer refer to anything. Alan to provide improved wording. |
| ]</i></p> |
| |
| |
| |
| <p><i>[ |
| Pre-Bellevue: Alisdair provided wording. |
| ]</i></p> |
| |
| |
| <p> |
| TR1 proposed resolution: |
| </p> |
| |
| <blockquote> |
| <p> |
| In TR1 3.6.3 [tr.func.bind.bind], add a new paragraph after p2: |
| </p> |
| <blockquote><p> |
| <i>Throws:</i> Nothing unless one of the copy constructors of <tt>f, t1, t2, ..., tN</tt> |
| throws an exception. |
| </p></blockquote> |
| |
| <p> |
| Add a new paragraph after p4: |
| </p> |
| <blockquote><p> |
| <i>Throws:</i> nothing unless one of the copy constructors of <tt>f, t1, t2, ..., tN</tt> |
| throws an exception. |
| </p></blockquote> |
| |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.6.11.1.3 [func.bind.bind], add a new paragraph after p2: |
| </p> |
| |
| <blockquote> |
| <i>Throws:</i> Nothing unless the copy constructor of <tt>F</tt> or of one of the types |
| in the <tt>BoundArgs...</tt> pack expansion throws an exception. |
| </blockquote> |
| |
| <p> |
| In 20.6.11.1.3 [func.bind.bind], add a new paragraph after p4: |
| </p> |
| |
| <blockquote> |
| <i>Throws:</i> Nothing unless the copy constructor of <tt>F</tt> or of one of the types |
| in the <tt>BoundArgs...</tt> pack expansion throws an exception. |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="530"></a>530. Must elements of a string be contiguous?</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2005-11-15</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#69">69</a>, which was incorporated into C++03, mandated |
| that the elements of a vector must be stored in contiguous memory. |
| Should the same also apply to <tt>basic_string</tt>?</p> |
| |
| <p>We almost require contiguity already. Clause 23.3.4 [multiset] |
| defines <tt>operator[]</tt> as <tt>data()[pos]</tt>. What's missing |
| is a similar guarantee if we access the string's elements via the |
| iterator interface.</p> |
| |
| <p>Given the existence of <tt>data()</tt>, and the definition of |
| <tt>operator[]</tt> and <tt>at</tt> in terms of <tt>data</tt>, |
| I don't believe it's possible to write a useful and standard- |
| conforming <tt>basic_string</tt> that isn't contiguous. I'm not |
| aware of any non-contiguous implementation. We should just require |
| it. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>Add the following text to the end of 21.3 [basic.string], |
| paragraph 2. </p> |
| |
| <blockquote> |
| <p>The characters in a string are stored contiguously, meaning that if |
| <tt>s</tt> is a <tt>basic_string<charT, Allocator></tt>, then |
| it obeys the identity |
| <tt>&*(s.begin() + n) == &*s.begin() + n</tt> |
| for all <tt>0 <= n < s.size()</tt>. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Not standardizing this existing practice does not give implementors more |
| freedom. We thought it might a decade ago. But the vendors have spoken |
| both with their implementations, and with their voice at the LWG |
| meetings. The implementations are going to be contiguous no matter what |
| the standard says. So the standard might as well give string clients |
| more design choices. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="531"></a>531. array forms of unformatted input functions</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2005-11-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The array forms of unformatted input functions don't seem to have well-defined |
| semantics for zero-element arrays in a couple of cases. The affected ones |
| (<tt>istream::get()</tt> and <tt>istream::getline()</tt>) are supposed to |
| terminate when <tt>(n - 1)</tt> characters are stored, which obviously can |
| never be true when <tt>(n == 0)</tt> holds to start with. See |
| c++std-lib-16071. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| I suggest changing 27.6.1.3, p7 (<tt>istream::get()</tt>), bullet 1 to read: |
| </p> |
| <ul> |
| <li> |
| <tt>(n < 1)</tt> is true or <tt>(n - 1)</tt> characters |
| are stored; |
| </li> |
| </ul> |
| <p> |
| Change 27.6.1.3, p9: |
| </p> |
| |
| <blockquote><p> |
| If the function stores no characters, it calls <tt>setstate(failbit)</tt> (which |
| may throw <tt>ios_base::failure</tt> (27.4.4.3)). In any case, <ins>if <tt>(n |
| > 0)</tt> is true</ins> it then stores a null character into the next |
| successive location of the array. |
| </p></blockquote> |
| |
| <p> |
| |
| and similarly p17 (<tt>istream::getline()</tt>), bullet 3 to: |
| |
| </p> |
| <ul> |
| <li> |
| <tt>(n < 1)</tt> is true or <tt>(n - 1)</tt> characters |
| are stored (in which case the function calls |
| <tt>setstate(failbit)</tt>). |
| </li> |
| </ul> |
| |
| <p> |
| |
| In addition, to clarify that <tt>istream::getline()</tt> must not store the |
| terminating NUL character unless the the array has non-zero size, Robert |
| Klarer suggests in c++std-lib-16082 to change 27.6.1.3, p20 to read: |
| |
| </p> |
| <blockquote><p> |
| |
| In any case, provided <tt>(n > 0)</tt> is true, it then stores a null character |
| (using charT()) into the next successive location of the array. |
| |
| </p></blockquote> |
| |
| <p><i>[ |
| post-Redmond: Pete noticed that the current resolution for <tt>get</tt> requires |
| writing to out of bounds memory when <tt>n == 0</tt>. Martin provided fix. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="533"></a>533. typo in 2.2.3.10/1</h3> |
| <p><b>Section:</b> 20.7.12.2.11 [util.smartptr.getdeleter], TR1 2.2.3.10 [tr.util.smartptr.getdeleter] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#DR">DR</a> |
| <b>Submitter:</b> Paolo Carlini <b>Date:</b> 2005-11-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.getdeleter">issues</a> in [util.smartptr.getdeleter].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#DR">DR</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I'm seeing something that looks like a typo. The Return of <tt>get_deleter</tt> |
| says: |
| </p> |
| <blockquote><p> |
| If <tt>*this</tt> <i>owns</i> a deleter <tt>d</tt>... |
| </p></blockquote> |
| <p> |
| but <tt>get_deleter</tt> is a free function! |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Therefore, I think should be: |
| </p> |
| <blockquote><p> |
| If <tt><del>*this</del> <ins>p</ins></tt> <i>owns</i> a deleter <tt>d</tt>... |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="534"></a>534. Missing basic_string members</h3> |
| <p><b>Section:</b> 21.3 [basic.string] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 2005-11-16</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#basic.string">active issues</a> in [basic.string].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#basic.string">issues</a> in [basic.string].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| OK, we all know std::basic_string is bloated and already has way too |
| many members. However, I propose it is missing 3 useful members that |
| are often expected by users believing it is a close approximation of the |
| container concept. All 3 are listed in table 71 as 'optional' |
| </p> |
| |
| <p> |
| i/ pop_back. |
| </p> |
| |
| <p> |
| This is the one I feel most strongly about, as I only just discovered it |
| was missing as we are switching to a more conforming standard library |
| <g> |
| </p> |
| |
| <p> |
| I find it particularly inconsistent to support push_back, but not |
| pop_back. |
| </p> |
| |
| <p> |
| ii/ back. |
| </p> |
| |
| <p> |
| There are certainly cases where I want to examine the last character of |
| a string before deciding to append, or to trim trailing path separators |
| from directory names etc. *rbegin() somehow feels inelegant. |
| </p> |
| |
| <p> |
| iii/ front |
| </p> |
| |
| <p> |
| This one I don't feel strongly about, but if I can get the first two, |
| this one feels that it should be added as a 'me too' for consistency. |
| </p> |
| |
| <p> |
| I believe this would be similarly useful to the data() member recently |
| added to vector, or at() member added to the maps. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following members to definition of class template basic_string, 21.3p7 |
| </p> |
| <blockquote><pre>void pop_back () |
| |
| const charT & front() const |
| charT & front() |
| |
| const charT & back() const |
| charT & back() |
| </pre></blockquote> |
| <p> |
| Add the following paragraphs to basic_string description |
| </p> |
| |
| <p> |
| 21.3.4p5 |
| </p> |
| <blockquote> |
| <pre>const charT & front() const |
| charT & front() |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>operator[](0)</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| 21.3.4p6 |
| </p> |
| <blockquote> |
| <pre>const charT & back() const |
| charT & back() |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>operator[]( size() - 1)</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| 21.3.5.5p10 |
| </p> |
| <blockquote> |
| <pre>void pop_back () |
| </pre> |
| <p> |
| <i>Precondition:</i> <tt>!empty()</tt> |
| </p> |
| <p> |
| <i>Effects:</i> Equivalent to <tt>erase( size() - 1, 1 )</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| Update Table 71: (optional sequence operations) |
| Add basic_string to the list of containers for the following operations. |
| </p> |
| <blockquote><pre>a.front() |
| a.back() |
| a.push_back() |
| a.pop_back() |
| a[n] |
| </pre></blockquote> |
| |
| <p><i>[ |
| Berlin: Has support. Alisdair provided wording. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="535"></a>535. std::string::swap specification poorly worded</h3> |
| <p><b>Section:</b> 21.3.6.8 [string::swap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2005-12-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string::swap">issues</a> in [string::swap].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| std::string::swap currently says for effects and postcondition: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Effects:</i> Swaps the contents of the two strings. |
| </p> |
| |
| <p> |
| <i>Postcondition:</i> <tt>*this</tt> contains the characters that were in <tt><i>s</i></tt>, |
| <tt><i>s</i></tt> contains the characters that were in <tt>*this</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| Specifying both Effects and Postcondition seems redundant, and the postcondition |
| needs to be made stronger. Users would be unhappy if the characters were not in |
| the same order after the swap. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <blockquote> |
| <p> |
| <del><i>Effects:</i> Swaps the contents of the two strings.</del> |
| </p> |
| |
| <p> |
| <i>Postcondition:</i> <tt>*this</tt> contains the <ins>same sequence of</ins> |
| characters that <del>were</del> <ins>was</ins> in <tt><i>s</i></tt>, |
| <tt><i>s</i></tt> contains the <ins>same sequence of</ins> characters that |
| <del>were</del> <ins>was</ins> in <tt>*this</tt>. |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="537"></a>537. Typos in the signatures in 27.6.1.3/42-43 and 27.6.2.4</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Paolo Carlini <b>Date:</b> 2006-02-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the most recent working draft, I'm still seeing: |
| </p> |
| |
| <blockquote><pre>seekg(off_type& off, ios_base::seekdir dir) |
| </pre></blockquote> |
| |
| <p> |
| and |
| </p> |
| |
| <blockquote><pre>seekp(pos_type& pos) |
| |
| seekp(off_type& off, ios_base::seekdir dir) |
| </pre></blockquote> |
| |
| <p> |
| that is, by reference off and pos arguments. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| After 27.6.1.3p42 change: |
| </p> |
| |
| <blockquote><pre>basic_istream<charT,traits>& seekg(off_type<del>&</del> <i>off</i>, ios_base::seekdir <i>dir</i>); |
| </pre></blockquote> |
| |
| <p> |
| After 27.6.2.4p1 change: |
| </p> |
| |
| <blockquote><pre>basic_ostream<charT,traits>& seekp(pos_type<del>&</del> <i>pos</i>); |
| </pre></blockquote> |
| |
| <p> |
| After 27.6.2.4p3 change: |
| </p> |
| |
| <blockquote><pre>basic_ostream<charT,traits>& seekp(off_type<del>&</del> <i>off</i>, ios_base::seekdir <i>dir</i>); |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="538"></a>538. 241 again: Does unique_copy() require CopyConstructible and Assignable?</h3> |
| <p><b>Section:</b> 25.2.9 [alg.unique] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2006-02-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.unique">issues</a> in [alg.unique].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I believe I botched the resolution of |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#241"> |
| 241 "Does unique_copy() require CopyConstructible and Assignable?"</a> which now |
| has WP status. |
| </p> |
| |
| <p> |
| This talks about <tt>unique_copy</tt> requirements and currently reads: |
| </p> |
| |
| <blockquote><p> |
| -5- <i>Requires:</i> The ranges <tt>[<i>first</i>, <i>last</i>)</tt> and |
| <tt>[<i>result</i>, <i>result</i>+(<i>last</i>-<i>first</i>))</tt> |
| shall not overlap. The expression <tt>*<i>result</i> = *<i>first</i></tt> shall |
| be valid. If neither <tt>InputIterator</tt> nor <tt>OutputIterator</tt> meets the |
| requirements of forward iterator then the value type of <tt>InputIterator</tt> |
| must be CopyConstructible (20.1.3). Otherwise CopyConstructible is not required. |
| </p></blockquote> |
| |
| <p> |
| The problem (which Paolo discovered) is that when the iterators are at their |
| most restrictive (<tt>InputIterator</tt>, <tt>OutputIterator</tt>), then we want |
| <tt>InputIterator::value_type</tt> to be both <tt>CopyConstructible</tt> and |
| <tt>CopyAssignable</tt> (for the most efficient implementation). However this |
| proposed resolution only makes it clear that it is <tt>CopyConstructible</tt>, |
| and that one can assign from <tt>*<i>first</i></tt> to <tt>*<i>result</i></tt>. |
| This latter requirement does not necessarily imply that you can: |
| </p> |
| |
| <blockquote><pre>*<i>first</i> = *<i>first</i>; |
| </pre></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <blockquote><p> |
| -5- <i>Requires:</i> The ranges <tt>[<i>first</i>, <i>last</i>)</tt> and |
| <tt>[<i>result</i>, <i>result</i>+(<i>last</i>-<i>first</i>))</tt> |
| shall not overlap. The expression <tt>*<i>result</i> = *<i>first</i></tt> |
| shall |
| be valid. If neither <tt>InputIterator</tt> nor <tt>OutputIterator</tt> meets the |
| requirements of forward iterator then the <del>value type</del> |
| <ins><tt>value_type</tt></ins> of <tt>InputIterator</tt> |
| must be CopyConstructible (20.1.3) <ins>and Assignable</ins>. |
| Otherwise CopyConstructible is not required. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="540"></a>540. shared_ptr<void>::operator*()</h3> |
| <p><b>Section:</b> 20.7.12.2.5 [util.smartptr.shared.obs], TR1 2.2.3.5 [tr.util.smartptr.shared.obs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2005-10-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared.obs">issues</a> in [util.smartptr.shared.obs].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I'm trying to reconcile the note in tr.util.smartptr.shared.obs, p6 |
| that talks about the operator*() member function of shared_ptr: |
| </p> |
| |
| <blockquote><p> |
| Notes: When T is void, attempting to instantiate this member function |
| renders the program ill-formed. [Note: Instantiating shared_ptr<void> |
| does not necessarily result in instantiating this member function. |
| --end note] |
| </p></blockquote> |
| |
| <p> |
| with the requirement in temp.inst, p1: |
| </p> |
| |
| <blockquote><p> |
| The implicit instantiation of a class template specialization causes |
| the implicit instantiation of the declarations, but not of the |
| definitions... |
| </p></blockquote> |
| |
| <p> |
| I assume that what the note is really trying to say is that |
| "instantiating shared_ptr<void> *must not* result in instantiating |
| this member function." That is, that this function must not be |
| declared a member of shared_ptr<void>. Is my interpretation |
| correct? |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 2.2.3.5p6 |
| </p> |
| |
| <blockquote><p> |
| -6- <del><i>Notes:</i></del> When <tt>T</tt> is <tt>void</tt>, <del>attempting to instantiate |
| this member function renders the program ill-formed. [<i>Note:</i> |
| Instantiating <tt>shared_ptr<void></tt> does not necessarily result in |
| instantiating this member function. <i>--end note</i>]</del> <ins>it is |
| unspecified whether this member function is declared or not, and if so, what its |
| return type is, except that the declaration (although not necessarily the |
| definition) of the function shall be well-formed.</ins> |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="541"></a>541. shared_ptr template assignment and void</h3> |
| <p><b>Section:</b> 20.7.12.2 [util.smartptr.shared], TR1 2.2.3 [tr.util.smartptr.shared] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2005-10-16</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#util.smartptr.shared">active issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared">issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Is the void specialization of the template assignment operator taking |
| a shared_ptr<void> as an argument supposed be well-formed? |
| </p> |
| <p> |
| I.e., is this snippet well-formed: |
| </p> |
| <blockquote><pre>shared_ptr<void> p; |
| p.operator=<void>(p); |
| </pre></blockquote> |
| |
| <p> |
| Gcc complains about auto_ptr<void>::operator*() returning a reference |
| to void. I suspect it's because shared_ptr has two template assignment |
| operators, one of which takes auto_ptr, and the auto_ptr template gets |
| implicitly instantiated in the process of overload resolution. |
| </p> |
| |
| <p> |
| The only way I see around it is to do the same trick with auto_ptr<void> |
| operator*() as with the same operator in shared_ptr<void>. |
| </p> |
| |
| <p> |
| PS Strangely enough, the EDG front end doesn't mind the code, even |
| though in a small test case (below) I can reproduce the error with |
| it as well. |
| </p> |
| |
| <blockquote><pre>template <class T> |
| struct A { T& operator*() { return *(T*)0; } }; |
| |
| template <class T> |
| struct B { |
| void operator= (const B&) { } |
| template <class U> |
| void operator= (const B<U>&) { } |
| template <class U> |
| void operator= (const A<U>&) { } |
| }; |
| |
| int main () |
| { |
| B<void> b; |
| b.operator=<void>(b); |
| } |
| </pre></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In [lib.memory] change: |
| </p> |
| <blockquote><pre>template<class X> class auto_ptr; |
| <ins>template<> class auto_ptr<void>;</ins> |
| </pre></blockquote> |
| |
| <p> |
| In [lib.auto.ptr]/2 add the following before the last closing brace: |
| </p> |
| |
| <blockquote><pre>template<> class auto_ptr<void> |
| { |
| public: |
| typedef void element_type; |
| }; |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="542"></a>542. shared_ptr observers</h3> |
| <p><b>Section:</b> 20.7.12.2.5 [util.smartptr.shared.obs], TR1 2.2.3.5 [tr.util.smartptr.shared.obs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2005-10-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared.obs">issues</a> in [util.smartptr.shared.obs].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Peter Dimov wrote: |
| To: C++ libraries mailing list |
| Message c++std-lib-15614 |
| [...] |
| The intent is for both use_count() and unique() to work in a threaded environment. |
| They are intrinsically prone to race conditions, but they never return garbage. |
| </p> |
| |
| <p> |
| This is a crucial piece of information that I really wish were |
| captured in the text. Having this in a non-normative note would |
| have made everything crystal clear to me and probably stopped |
| me from ever starting this discussion :) Instead, the sentence |
| in p12 "use only for debugging and testing purposes, not for |
| production code" very strongly suggests that implementations |
| can and even are encouraged to return garbage (when threads |
| are involved) for performance reasons. |
| </p> |
| <p> |
| How about adding an informative note along these lines: |
| </p> |
| <blockquote><p> |
| Note: Implementations are encouraged to provide well-defined |
| behavior for use_count() and unique() even in the presence of |
| multiple threads. |
| </p></blockquote> |
| <p> |
| I don't necessarily insist on the exact wording, just that we |
| capture the intent. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 20.7.12.2.5 [util.smartptr.shared.obs] p12: |
| </p> |
| <blockquote><p> |
| [<i>Note:</i> <tt>use_count()</tt> is not necessarily efficient. <del>Use only for |
| debugging and testing purposes, not for production code.</del> --<i>end note</i>] |
| </p></blockquote> |
| |
| <p> |
| Change 20.7.12.3.5 [util.smartptr.weak.obs] p3: |
| </p> |
| <blockquote><p> |
| [<i>Note:</i> <tt>use_count()</tt> is not necessarily efficient. <del>Use only for |
| debugging and testing purposes, not for production code.</del> --<i>end note</i>] |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="543"></a>543. valarray slice default constructor</h3> |
| <p><b>Section:</b> 26.5.4 [class.slice] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2005-11-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| If one explicitly constructs a slice or glice with the default |
| constructor, does the standard require this slice to have any usable |
| state? It says "creates a slice which specifies no elements", which |
| could be interpreted two ways: |
| </p> |
| <ol> |
| <li>There are no elements to which the slice refers (i.e. undefined).</li> |
| <li>The slice specifies an array with no elements in it (i.e. defined).</li> |
| </ol> |
| <p> |
| Here is a bit of code to illustrate: |
| </p> |
| <blockquote><pre>#include <iostream> |
| #include <valarray> |
| |
| int main() |
| { |
| std::valarray<int> v(10); |
| std::valarray<int> v2 = v[std::slice()]; |
| std::cout << "v[slice()].size() = " << v2.size() << '\n'; |
| } |
| </pre></blockquote> |
| |
| <p> |
| Is the behavior undefined? Or should the output be: |
| </p> |
| |
| <blockquote><pre>v[slice()].size() = 0 |
| </pre></blockquote> |
| |
| <p> |
| There is a similar question and wording for gslice at 26.3.6.1p1. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[Martin suggests removing the second sentence in 26.5.4.1 [cons.slice] as well.]</i></p> |
| |
| |
| <p> |
| Change 26.5.4.1 [cons.slice]: |
| </p> |
| |
| <blockquote><p> |
| 1 - <del>The default constructor for <tt>slice</tt> creates a <tt>slice</tt> |
| which specifies no elements.</del> <ins>The default constructor is equivalent to |
| <tt>slice(0, 0, 0)</tt>.</ins> A default constructor is provided only to permit |
| the declaration of arrays of slices. The constructor with arguments for a slice |
| takes a start, length, and stride parameter. |
| </p></blockquote> |
| |
| <p> |
| Change 26.5.6.1 [gslice.cons]: |
| </p> |
| |
| <blockquote><p> |
| 1 - <del>The default constructor creates a <tt>gslice</tt> which specifies no |
| elements.</del> <ins>The default constructor is equivalent to <tt>gslice(0, |
| valarray<size_t>(), valarray<size_t>())</tt>.</ins> The constructor |
| with arguments builds a <tt>gslice</tt> based on a specification of start, |
| lengths, and strides, as explained in the previous section. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="545"></a>545. When is a deleter deleted?</h3> |
| <p><b>Section:</b> 20.7.12.2.11 [util.smartptr.getdeleter], TR1 2.2.3.2 [tr.util.smartptr.shared.dest] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2006-01-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.getdeleter">issues</a> in [util.smartptr.getdeleter].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The description of ~shared_ptr doesn't say when the shared_ptr's deleter, if |
| any, is destroyed. In principle there are two possibilities: it is destroyed |
| unconditionally whenever ~shared_ptr is executed (which, from an implementation |
| standpoint, means that the deleter is copied whenever the shared_ptr is copied), |
| or it is destroyed immediately after the owned pointer is destroyed (which, from |
| an implementation standpoint, means that the deleter object is shared between |
| instances). We should say which it is. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add after the first sentence of 20.7.12.2.11 [util.smartptr.getdeleter]/1: |
| </p> |
| <blockquote> |
| <p> |
| The returned pointer remains valid as long as there exists a <tt>shared_ptr</tt> instance |
| that owns <tt><i>d</i></tt>. |
| </p> |
| <p> |
| [<i>Note:</i> it is unspecified whether the pointer remains valid longer than that. |
| This can happen if the implementation doesn't destroy the deleter until all |
| <tt>weak_ptr</tt> instances in the ownership group are destroyed. <i>-- end note</i>] |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="550"></a>550. What should the return type of pow(float,int) be?</h3> |
| <p><b>Section:</b> 26.7 [c.math] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2006-01-12</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#c.math">issues</a> in [c.math].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Assuming we adopt the |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">C |
| compatibility package from C99</a> what should be the return type of the |
| following signature be: |
| </p> |
| <blockquote><pre>? pow(float, int); |
| </pre></blockquote> |
| <p> |
| C++03 says that the return type should be <tt>float</tt>. |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf"> |
| TR1</a> and C90/99 say the return type should be <tt>double</tt>. This can put |
| clients into a situation where C++03 provides answers that are not as high |
| quality as C90/C99/TR1. For example: |
| </p> |
| <blockquote><pre>#include <math.h> |
| |
| int main() |
| { |
| float x = 2080703.375F; |
| double y = pow(x, 2); |
| } |
| </pre></blockquote> |
| <p> |
| Assuming an IEEE 32 bit float and IEEE 64 bit double, C90/C99/TR1 all suggest: |
| </p> |
| |
| <blockquote><pre>y = 4329326534736.390625 |
| </pre></blockquote> |
| |
| <p> |
| which is exactly right. While C++98/C++03 demands: |
| </p> |
| |
| <blockquote><pre>y = 4329326510080. |
| </pre></blockquote> |
| |
| <p> |
| which is only approximately right. |
| </p> |
| |
| <p> |
| I recommend that C++0X adopt the mixed mode arithmetic already adopted by |
| Fortran, C and TR1 and make the return type of <tt>pow(float,int)</tt> be |
| <tt>double</tt>. |
| </p> |
| |
| <p><i>[ |
| Kona (2007): Other functions that are affected by this issue include |
| <tt>ldexp</tt>, <tt>scalbln</tt>, and <tt>scalbn</tt>. We also believe that there is a typo in |
| 26.7/10: <tt>float nexttoward(float, long double);</tt> [sic] should be <tt>float |
| nexttoward(float, float);</tt> Proposed Disposition: Review (the proposed |
| resolution appears above, rather than below, the heading "Proposed |
| resolution") |
| ]</i></p> |
| |
| |
| <p><i>[ |
| <p> |
| Howard, post Kona: |
| </p> |
| <blockquote> |
| <p> |
| Unfortunately I strongly disagree with a part of the resolution |
| from Kona. I am moving from New to Open instead of to Review because I do not believe |
| we have consensus on the intent of the resolution. |
| </p> |
| <p> |
| This issue does not include <tt>ldexp</tt>, <tt>scalbln</tt>, and <tt>scalbn</tt> because |
| the second integral parameter in each of these signatures (from C99) is <b>not</b> a |
| <i>generic parameter</i> according to C99 7.22p2. The corresponding C++ overloads are |
| intended (as far as I know) to correspond directly to C99's definition of <i>generic parameter</i>. |
| </p> |
| <p> |
| For similar reasons, I do not believe that the second <tt>long double</tt> parameter of |
| <tt>nexttoward</tt>, nor the return type of this function, is in error. I believe the |
| correct signature is: |
| </p> |
| <blockquote> |
| <pre>float nexttoward(float, long double); |
| </pre> |
| </blockquote> |
| <p> |
| which is what both the C++0X working paper and C99 state (as far as I currently understand). |
| </p> |
| <p> |
| This is really <b>only</b> about <tt>pow(float, int)</tt>. And this is because C++98 took one |
| route (with <tt>pow</tt> only) and C99 took another (with many math functions in <tt><tgmath.h></tt>. |
| The proposed resolution basically says: C++98 got it wrong and C99 got it right; let's go with C99. |
| </p> |
| </blockquote> |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| This signature was not picked up from C99. Instead, if one types |
| pow(2.0f,2), the promotion rules will invoke "double pow(double, |
| double)", which generally gives special treatment for integral |
| exponents, preserving full accuracy of the result. New proposed |
| wording provided. |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.7 [c.math] p10: |
| </p> |
| |
| <blockquote> |
| <p> |
| The added signatures are: |
| </p> |
| <blockquote><pre>... |
| <del>float pow(float, int);</del> |
| ... |
| <del>double pow(double, int);</del> |
| ... |
| <del>long double pow(long double, int);</del> |
| </pre></blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="551"></a>551. <ccomplex></h3> |
| <p><b>Section:</b> 26.3.11 [cmplxh], TR1 8.3 [tr.c99.cmplxh] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2006-01-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Previously xxx.h was parsable by C++. But in the case of C99's <complex.h> |
| it isn't. Otherwise we could model it just like <string.h>, <cstring>, <string>: |
| </p> |
| |
| <ul> |
| <li><string> : C++ API in namespace std</li> |
| <li><cstring> : C API in namespace std</li> |
| <li><string.h> : C API in global namespace</li> |
| </ul> |
| |
| <p> |
| In the case of C's complex, the C API won't compile in C++. So we have: |
| </p> |
| |
| <ul> |
| <li><complex> : C++ API in namespace std</li> |
| <li><ccomplex> : ?</li> |
| <li><complex.h> : ?</li> |
| </ul> |
| |
| <p> |
| The ? can't refer to the C API. TR1 currently says: |
| </p> |
| |
| <ul> |
| <li><complex> : C++ API in namespace std</li> |
| <li><ccomplex> : C++ API in namespace std</li> |
| <li><complex.h> : C++ API in global namespace</li> |
| </ul> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.3.11 [cmplxh]: |
| </p> |
| |
| <blockquote> |
| <p> |
| The header behaves as if it includes the header |
| <tt><ccomplex></tt><ins>.</ins><del>, and provides sufficient using |
| declarations to declare in the global namespace all function and type names |
| declared or defined in the neader <tt><complex></tt>.</del> |
| <ins>[<i>Note:</i> <tt><complex.h></tt> does not promote any interface |
| into the global namespace as there is no C interface to promote. <i>--end |
| note</i>]</ins> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="552"></a>552. random_shuffle and its generator</h3> |
| <p><b>Section:</b> 25.2.12 [alg.random.shuffle] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-01-25</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| ...is specified to shuffle its range by calling swap but not how |
| (or even that) it's supposed to use the RandomNumberGenerator |
| argument passed to it. |
| </p> |
| <p> |
| Shouldn't we require that the generator object actually be used |
| by the algorithm to obtain a series of random numbers and specify |
| how many times its operator() should be invoked by the algorithm? |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="559"></a>559. numeric_limits<const T></h3> |
| <p><b>Section:</b> 18.2.1 [limits] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-02-19</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#limits">issues</a> in [limits].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| 18.2.1 [limits], p2 requires implementations to provide specializations of the |
| <code>numeric_limits</code> template for each scalar type. While this |
| could be interepreted to include cv-qualified forms of such types such |
| an interepretation is not reflected in the synopsis of the |
| <code><limits></code> header. |
| |
| </p> |
| <p> |
| |
| The absence of specializations of the template on cv-qualified forms |
| of fundamental types makes <code>numeric_limits</code> difficult to |
| use in generic code where the constness (or volatility) of a type is |
| not always immediately apparent. In such contexts, the primary |
| template ends up being instantiated instead of the provided |
| specialization, typically yielding unexpected behavior. |
| |
| </p> |
| <p> |
| |
| Require that specializations of <code>numeric_limits</code> on |
| cv-qualified fundamental types have the same semantics as those on the |
| unqualifed forms of the same types. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Add to the synopsis of the <code><limits></code> header, |
| immediately below the declaration of the primary template, the |
| following: |
| </p> |
| |
| <pre> |
| template <class T> class numeric_limits<const T>; |
| template <class T> class numeric_limits<volatile T>; |
| template <class T> class numeric_limits<const volatile T>; |
| |
| </pre> |
| |
| <p> |
| |
| Add a new paragraph to the end of 18.2.1.1 [numeric.limits], with the following |
| text: |
| |
| </p> |
| <p> |
| |
| -new-para- The value of each member of a <code>numeric_limits</code> |
| specialization on a cv-qualified T is equal to the value of the same |
| member of <code>numeric_limits<T></code>. |
| |
| </p> |
| |
| <p><i>[ |
| Portland: Martin will clarify that user-defined types get cv-specializations |
| automatically. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="561"></a>561. inserter overly generic</h3> |
| <p><b>Section:</b> 24.4.2.6.5 [inserter] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2006-02-21</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The declaration of <tt>std::inserter</tt> is: |
| </p> |
| |
| <blockquote><pre>template <class Container, class Iterator> |
| insert_iterator<Container> |
| inserter(Container& x, Iterator i); |
| </pre></blockquote> |
| |
| <p> |
| The template parameter <tt>Iterator</tt> in this function is completely unrelated |
| to the template parameter <tt>Container</tt> when it doesn't need to be. This |
| causes the code to be overly generic. That is, any type at all can be deduced |
| as <tt>Iterator</tt>, whether or not it makes sense. Now the same is true of |
| <tt>Container</tt>. However, for every free (unconstrained) template parameter |
| one has in a signature, the opportunity for a mistaken binding grows geometrically. |
| </p> |
| |
| <p> |
| It would be much better if <tt>inserter</tt> had the following signature instead: |
| </p> |
| |
| <blockquote><pre>template <class Container> |
| insert_iterator<Container> |
| inserter(Container& x, typename Container::iterator i); |
| </pre></blockquote> |
| |
| <p> |
| Now there is only one free template parameter. And the second argument to |
| <tt>inserter</tt> must be implicitly convertible to the container's iterator, |
| else the call will not be a viable overload (allowing other functions in the |
| overload set to take precedence). Furthermore, the first parameter must have a |
| nested type named <tt>iterator</tt>, or again the binding to <tt>std::inserter</tt> |
| is not viable. Contrast this with the current situation |
| where any type can bind to <tt>Container</tt> or <tt>Iterator</tt> and those |
| types need not be anything closely related to containers or iterators. |
| </p> |
| |
| <p> |
| This can adversely impact well written code. Consider: |
| </p> |
| |
| <blockquote><pre>#include <iterator> |
| #include <string> |
| |
| namespace my |
| { |
| |
| template <class String> |
| struct my_type {}; |
| |
| struct my_container |
| { |
| template <class String> |
| void push_back(const my_type<String>&); |
| }; |
| |
| template <class String> |
| void inserter(const my_type<String>& m, my_container& c) {c.push_back(m);} |
| |
| } // my |
| |
| int main() |
| { |
| my::my_container c; |
| my::my_type<std::string> m; |
| inserter(m, c); |
| } |
| </pre></blockquote> |
| |
| <p> |
| Today this code fails because the call to <tt>inserter</tt> binds to |
| <tt>std::inserter</tt> instead of to <tt>my::inserter</tt>. However with the |
| proposed change <tt>std::inserter</tt> will no longer be a viable function which |
| leaves only <tt>my::inserter</tt> in the overload resolution set. Everything |
| works as the client intends. |
| </p> |
| |
| <p> |
| To make matters a little more insidious, the above example works today if you |
| simply change the first argument to an rvalue: |
| </p> |
| |
| <blockquote><pre> inserter(my::my_type(), c); |
| </pre></blockquote> |
| |
| <p> |
| It will also work if instantiated with some string type other than |
| <tt>std::string</tt> (or any other <tt>std</tt> type). It will also work if |
| <tt><iterator></tt> happens to not get included. |
| </p> |
| |
| <p> |
| And it will fail again for such inocuous reaons as <tt>my_type</tt> or |
| <tt>my_container</tt> privately deriving from any <tt>std</tt> type. |
| </p> |
| |
| <p> |
| It seems unfortunate that such simple changes in the client's code can result |
| in such radically differing behavior. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 24.2: |
| </p> |
| |
| <blockquote><p> |
| <b>24.2 Header</b> <tt><iterator></tt> <b>synopsis</b> |
| </p> |
| <blockquote><pre>... |
| template <class Container<del>, class Iterator</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Iterator</del> <ins>typename Container::iterator</ins> i); |
| ... |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| Change 24.4.2.5: |
| </p> |
| |
| <blockquote><p> |
| <b>24.4.2.5 Class template</b> <tt>insert_iterator</tt></p> |
| <blockquote><pre>... |
| template <class Container<del>, class Iterator</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Iterator</del> <ins>typename Container::iterator</ins> i); |
| ... |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| Change 24.4.2.6.5: |
| </p> |
| |
| <blockquote> |
| <p> |
| <b>24.4.2.6.5</b> <tt>inserter</tt> |
| </p> |
| <pre>template <class Container<del>, class Inserter</del>> |
| insert_iterator<Container> inserter(Container& x, <del>Inserter</del> <ins>typename Container::iterator</ins> i); |
| </pre> |
| <blockquote><p> |
| -1- <i>Returns:</i> <tt>insert_iterator<Container>(x,<del>typename Container::iterator(</del>i<del>)</del>)</tt>. |
| </p></blockquote> |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): This issue will probably be addressed as a part of the |
| concepts overhaul of the library anyway, but the proposed resolution is |
| correct in the absence of concepts. Proposed Disposition: Ready |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="562"></a>562. stringbuf ctor inefficient</h3> |
| <p><b>Section:</b> 27.7 [string.streams] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-02-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.streams">issues</a> in [string.streams].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| For better efficiency, the requirement on the stringbuf ctor that |
| takes a string argument should be loosened up to let it set |
| <code>epptr()</code> beyond just one past the last initialized |
| character just like <code>overflow()</code> has been changed to be |
| allowed to do (see issue 432). That way the first call to |
| <code>sputc()</code> on an object won't necessarily cause a call to |
| <code>overflow</code>. The corresponding change should be made to the |
| string overload of the <code>str()</code> member function. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Change 27.7.1.1, p3 of the Working Draft, N1804, as follows: |
| |
| </p> |
| |
| <blockquote><pre>explicit basic_stringbuf(const basic_string<charT,traits,Allocator>& <i>s<del>tr</del></i>, |
| ios_base::openmode <i>which</i> = ios_base::in | ios_base::out); |
| </pre> |
| |
| <p> |
| -3- <i>Effects:</i> Constructs an object of class <tt>basic_stringbuf</tt>, |
| initializing the base class with <tt>basic_streambuf()</tt> |
| (27.5.2.1), and initializing <tt><i>mode</i></tt> with <tt><i>which</i></tt>. |
| Then <ins>calls <tt>str(<i>s</i>)</tt>.</ins> <del>copies the content of |
| <i>str</i> into the <tt>basic_stringbuf</tt> underlying character |
| sequence. If <tt><i>which</i> & ios_base::out</tt> is true, initializes the |
| output sequence such that <tt>pbase()</tt> points to the first underlying |
| character, <tt>epptr()</tt> points one past the last underlying character, and |
| <tt>pptr()</tt> is equal to <tt>epptr()</tt> if <tt><i>which</i> & ios_base::ate</tt> |
| is true, otherwise <tt>pptr()</tt> is equal to <tt>pbase()</tt>. If |
| <tt>which & ios_base::in</tt> is true, initializes the input sequence such |
| that <tt>eback()</tt> and <tt>gptr()</tt> point to the first underlying |
| character and <tt>egptr()</tt> points one past the last underlying character.</del> |
| </p> |
| </blockquote> |
| |
| <p> |
| |
| Change the Effects clause of the <code>str()</code> in 27.7.1.2, p2 to |
| read: |
| |
| </p> |
| <blockquote> |
| <p> |
| -2- <i>Effects:</i> Copies the content<ins>s</ins> of <tt><i>s</i></tt> into the |
| <tt>basic_stringbuf</tt> underlying character sequence <ins>and |
| initializes the input and output sequences according to <tt><i>mode</i></tt></ins>. |
| <del>If |
| <tt><i>mode</i> & ios_base::out</tt> is true, initializes the output |
| sequence such that <tt>pbase()</tt> points to the first underlying character, |
| <tt>epptr()</tt> points one past the last underlying character, and <tt>pptr()</tt> |
| is equal to <tt>epptr()</tt> if <tt><i>mode</i> & ios_base::in</tt> |
| is true, otherwise <tt>pptr()</tt> is equal to <tt>pbase()</tt>. If |
| <tt>mode & ios_base::in</tt> is true, initializes the input sequence |
| such that <tt>eback()</tt> and <tt>gptr()</tt> point to the first underlying |
| character and <tt>egptr()</tt> points one past the last underlying character.</del> |
| </p> |
| |
| <p> |
| |
| <ins>-3- <i>Postconditions:</i> If <code>mode & ios_base::out</code> is true, |
| <code>pbase()</code> points to the first underlying character and |
| <code>(epptr() >= pbase() + s.size())</code> holds; in addition, if |
| <code>mode & ios_base::in</code> is true, <code>(pptr() == pbase() |
| + s.data())</code> holds, otherwise <code>(pptr() == pbase())</code> |
| is true. If <code>mode & ios_base::in</code> is true, |
| <code>eback()</code> points to the first underlying character, and |
| <code>(gptr() == eback())</code> and <code>(egptr() == eback() + |
| s.size())</code> hold.</ins> |
| |
| </p> |
| </blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007) Moved to Ready. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="563"></a>563. stringbuf seeking from end</h3> |
| <p><b>Section:</b> 27.7.1.4 [stringbuf.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-02-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#stringbuf.virtuals">issues</a> in [stringbuf.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| According to Table 92 (unchanged by issue 432), when <code>(way == |
| end)</code> the <code>newoff</code> value in out mode is computed as |
| the difference between <code>epptr()</code> and <code>pbase()</code>. |
| </p> |
| <p> |
| |
| This value isn't meaningful unless the value of <code>epptr()</code> |
| can be precisely controlled by a program. That used to be possible |
| until we accepted the resolution of issue 432, but since then the |
| requirements on <code>overflow()</code> have been relaxed to allow it |
| to make more than 1 write position available (i.e., by setting |
| <code>epptr()</code> to some unspecified value past |
| <code>pptr()</code>). So after the first call to |
| <code>overflow()</code> positioning the output sequence relative to |
| end will have unspecified results. |
| |
| </p> |
| <p> |
| |
| In addition, in <code>in|out</code> mode, since <code>(egptr() == |
| epptr())</code> need not hold, there are two different possible values |
| for <code>newoff</code>: <code>epptr() - pbase()</code> and |
| <code>egptr() - eback()</code>. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Change the <code>newoff</code> column in the last row of Table 94 to |
| read: |
| |
| </p> |
| <blockquote><p> |
| |
| the <del>end</del> <ins>high mark</ins> pointer minus the beginning |
| pointer (<code><del>xend</del> <ins>high_mark</ins> - xbeg</code>). |
| |
| </p></blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007) Moved to Ready. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="566"></a>566. array forms of unformatted input function undefined for zero-element arrays</h3> |
| <p><b>Section:</b> 27.6.1.3 [istream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-02-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.unformatted">issues</a> in [istream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The array forms of unformatted input functions don't have well-defined |
| semantics for zero-element arrays in a couple of cases. The affected |
| ones (<tt>istream::get()</tt> and <tt>getline()</tt>) are supposed to |
| terminate when <tt>(n - 1)</tt> characters are stored, which obviously |
| can never be true when <tt>(n == 0)</tt> to start with. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose the following changes (references are relative to the |
| Working Draft (document N1804). |
| |
| </p> |
| <p> |
| |
| Change 27.6.1.3, p8 (<tt>istream::get()</tt>), bullet 1 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <ins>if <tt>(n < 1)</tt> is true or </ins> <tt>(n - 1)</tt> |
| characters are stored; |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| Similarly, change 27.6.1.3, p18 (<tt>istream::getline()</tt>), bullet |
| 3 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <ins><tt>(n < 1)</tt> is true or </ins><tt>(n - 1)</tt> characters |
| are stored (in which case the function calls |
| <tt>setstate(failbit)</tt>). |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| Finally, change p21 as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| In any case, <ins>provided <tt>(n > 0)</tt> is true, </ins>it then |
| stores a null character (using charT()) into the next successive |
| location of the array. |
| |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="567"></a>567. streambuf inserter and extractor should be unformatted</h3> |
| <p><b>Section:</b> 27.6 [iostream.format] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-02-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostream.format">issues</a> in [iostream.format].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| Issue 60 explicitly made the extractor and inserter operators that |
| take a <tt>basic_streambuf*</tt> argument formatted input and output |
| functions, respectively. I believe that's wrong, certainly in the |
| case of the extractor, since formatted functions begin by extracting |
| and discarding whitespace. The extractor should not discard any |
| characters. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to change each operator to behave as unformatted input and |
| output function, respectively. The changes below are relative to the |
| working draft document number N1804. |
| |
| </p> |
| <p> |
| |
| Specifically, change 27.6.1.2.3, p14 as follows: |
| |
| </p> |
| |
| <blockquote> |
| <p> |
| |
| <i>Effects</i>: Behaves as a<ins>n un</ins>formatted input function |
| (as described in <del>27.6.1.2.1</del><ins>27.6.1.3, paragraph |
| 1</ins>). |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| And change 27.6.2.5.3, p7 as follows: |
| |
| </p> |
| |
| <blockquote> |
| <p> |
| |
| <i>Effects</i>: Behaves as a<ins>n un</ins>formatted output function |
| (as described in <del>27.6.2.5.1</del><ins>27.6.2.6, paragraph |
| 1</ins>). |
| |
| </p> |
| </blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007): Proposed Disposition: Ready |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="574"></a>574. DR 369 Contradicts Text</h3> |
| <p><b>Section:</b> 27.3 [iostream.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Pete Becker <b>Date:</b> 2006-04-18</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#iostream.objects">issues</a> in [iostream.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| lib.iostream.objects requires that the standard stream objects are never |
| destroyed, and it requires that they be destroyed. |
| </p> |
| <p> |
| DR 369 adds words to say that we really mean for ios_base::Init objects to force |
| construction of standard stream objects. It ends, though, with the phrase "these |
| stream objects shall be destroyed after the destruction of dynamically ...". |
| However, the rule for destruction is stated in the standard: "The objects are |
| not destroyed during program execution." |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 27.3 [iostream.objects]/1: |
| </p> |
| |
| <blockquote> |
| <p> |
| -2- The objects are constructed and the associations are established at |
| some time prior to or during the first time an object of class |
| <tt>ios_base::Init</tt> is constructed, and in any case before the body of main |
| begins execution.<sup>290)</sup> The objects are not destroyed during program |
| execution.<sup>291)</sup> If a translation unit includes <tt><iostream&t;</tt> or explicitly |
| constructs an <tt>ios_base::Init</tt> object, these stream objects shall be |
| constructed before dynamic initialization of non-local objects defined |
| later in that translation unit<del>, and these stream objects shall be |
| destroyed after the destruction of dynamically initialized non-local |
| objects defined later in that translation unit</del>. |
| </p> |
| </blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007): From 27.3 [iostream.objects]/2, strike the words "...and these stream objects |
| shall be destroyed after the destruction of dynamically initialized |
| non-local objects defined later in that translation unit." Proposed |
| Disposition: Review |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="575"></a>575. the specification of ~shared_ptr is MT-unfriendly, makes implementation assumptions</h3> |
| <p><b>Section:</b> 20.7.12.2.2 [util.smartptr.shared.dest], TR1 2.2.3.2 [tr.util.smartptr.shared.dest] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2006-04-23</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| [tr.util.smartptr.shared.dest] says in its second bullet: |
| </p> |
| |
| <p> |
| "If *this shares ownership with another shared_ptr instance (use_count() > 1), |
| decrements that instance's use count." |
| </p> |
| |
| <p> |
| The problem with this formulation is that it presupposes the existence of an |
| "use count" variable that can be decremented and that is part of the state of a |
| shared_ptr instance (because of the "that instance's use count".) |
| </p> |
| |
| <p> |
| This is contrary to the spirit of the rest of the specification that carefully |
| avoids to require an use count variable. Instead, use_count() is specified to |
| return a value, a number of instances. |
| </p> |
| |
| <p> |
| In multithreaded code, the usual implicit assumption is that a shared variable |
| should not be accessed by more than one thread without explicit synchronization, |
| and by introducing the concept of an "use count" variable, the current wording |
| implies that two shared_ptr instances that share ownership cannot be destroyed |
| simultaneously. |
| </p> |
| |
| <p> |
| In addition, if we allow the interpretation that an use count variable is part |
| of shared_ptr's state, this would lead to other undesirable consequences WRT |
| multiple threads. For example, |
| </p> |
| |
| <blockquote><pre>p1 = p2; |
| </pre></blockquote> |
| |
| <p> |
| would now visibly modify the state of p2, a "write" operation, requiring a lock. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first two bullets of [lib.util.smartptr.shared.dest]/1 to: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li>If <tt>*this</tt> is <i>empty</i> <ins>or shares ownership with another |
| <tt>shared_ptr</tt> instance (<tt>use_count() > 1</tt>)</ins>, there are no side effects.</li> |
| <li><del>If <tt>*this</tt> <i>shares ownership</i> with another <tt>shared_ptr</tt> instance |
| (<tt>use_count() > 1</tt>), decrements that instance's use count.</del></li> |
| </ul> |
| </blockquote> |
| |
| <p> |
| Add the following paragraph after [lib.util.smartptr.shared.dest]/1: |
| </p> |
| |
| <blockquote><p> |
| [<i>Note:</i> since the destruction of <tt>*this</tt> decreases the number of instances in |
| <tt>*this</tt>'s ownership group by one, all <tt>shared_ptr</tt> instances that share ownership |
| with <tt>*this</tt> will report an <tt>use_count()</tt> that is one lower than its previous value |
| after <tt>*this</tt> is destroyed. <i>--end note</i>] |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="576"></a>576. find_first_of is overconstrained</h3> |
| <p><b>Section:</b> 25.1.7 [alg.find.first.of] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Doug Gregor <b>Date:</b> 2006-04-25</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.find.first.of">issues</a> in [alg.find.first.of].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 25.1.4 Find First [lib.alg.find.first], the two iterator type parameters to |
| find_first_of are specified to require Forward Iterators, as follows: |
| </p> |
| |
| <blockquote><pre>template<class ForwardIterator1, class ForwardIterator2> |
| ForwardIterator1 |
| find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, |
| ForwardIterator2 first2, ForwardIterator2 last2); |
| template<class ForwardIterator1, class ForwardIterator2, |
| class BinaryPredicate> |
| ForwardIterator1 |
| find_first_of(ForwardIterator1 first1, ForwardIterator1 last1, |
| ForwardIterator2 first2, ForwardIterator2 last2, |
| BinaryPredicate pred); |
| </pre></blockquote> |
| |
| <p> |
| However, ForwardIterator1 need not actually be a Forward Iterator; an Input |
| Iterator suffices, because we do not need the multi-pass property of the Forward |
| Iterator or a true reference. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the declarations of <tt>find_first_of</tt> to: |
| </p> |
| |
| <blockquote><pre>template<class <del>ForwardIterator1</del><ins>InputIterator1</ins>, class ForwardIterator2> |
| <del>ForwardIterator1</del><ins>InputIterator1</ins> |
| find_first_of(<del>ForwardIterator1</del><ins>InputIterator1</ins> first1, <del>ForwardIterator1</del><ins>InputIterator1</ins> last1, |
| ForwardIterator2 first2, ForwardIterator2 last2); |
| template<class <del>ForwardIterator1</del><ins>InputIterator1</ins>, class ForwardIterator2, |
| class BinaryPredicate> |
| <del>ForwardIterator1</del><ins>InputIterator1</ins> |
| find_first_of(<del>ForwardIterator1</del><ins>InputIterator1</ins> first1, <del>ForwardIterator1</del><ins>InputIterator1</ins> last1, |
| ForwardIterator2 first2, ForwardIterator2 last2, |
| BinaryPredicate pred); |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="577"></a>577. upper_bound(first, last, ...) cannot return last</h3> |
| <p><b>Section:</b> 25.3.3.2 [upper.bound] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Seungbeom Kim <b>Date:</b> 2006-05-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| ISO/IEC 14882:2003 says: |
| </p> |
| |
| <blockquote> |
| <p> |
| 25.3.3.2 upper_bound |
| </p> |
| <p> |
| <i>Returns:</i> The furthermost iterator <tt>i</tt> in the range |
| <tt>[<i>first</i>, <i>last</i>)</tt> such that |
| for any iterator <tt>j</tt> in the range <tt>[<i>first</i>, i)</tt> the following corresponding |
| conditions hold: <tt>!(value < *j)</tt> or <tt><i>comp</i>(<i>value</i>, *j) == false</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| From the description above, upper_bound cannot return last, since it's |
| not in the interval [first, last). This seems to be a typo, because if |
| value is greater than or equal to any other values in the range, or if |
| the range is empty, returning last seems to be the intended behaviour. |
| The corresponding interval for lower_bound is also [first, last]. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change [lib.upper.bound]: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Returns:</i> The furthermost iterator <tt>i</tt> in the range |
| <tt>[<i>first</i>, <i>last</i><del>)</del><ins>]</ins></tt> such that |
| for any iterator <tt>j</tt> in the range <tt>[<i>first</i>, i)</tt> the following corresponding |
| conditions hold: <tt>!(value < *j)</tt> or <tt><i>comp</i>(<i>value</i>, *j) == false</tt>. |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="578"></a>578. purpose of hint to allocator::allocate()</h3> |
| <p><b>Section:</b> 20.7.5.1 [allocator.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-05-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.members">issues</a> in [allocator.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The description of the allocator member function |
| <code>allocate()</code> requires that the <i>hint</i> argument be |
| either 0 or a value previously returned from <code>allocate()</code>. |
| Footnote 227 further suggests that containers may pass the address of |
| an adjacent element as this argument. |
| |
| </p> |
| <p> |
| |
| I believe that either the footnote is wrong or the normative |
| requirement that the argument be a value previously returned from a |
| call to <code>allocate()</code> is wrong. The latter is supported by |
| the resolution to issue 20-004 proposed in c++std-lib-3736 by Nathan |
| Myers. In addition, the <i>hint</i> is an ordinary void* and not the |
| <code>pointer</code> type returned by <code>allocate()</code>, with |
| the two types potentially being incompatible and the requirement |
| impossible to satisfy. |
| |
| </p> |
| <p> |
| |
| See also c++std-lib-14323 for some more context on where this came up |
| (again). |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Remove the requirement in 20.6.1.1, p4 that the hint be a value |
| previously returned from <code>allocate()</code>. Specifically, change |
| the paragraph as follows: |
| |
| </p> |
| <p> |
| <del><i>Requires</i>: <i>hint</i> either 0 or previously obtained from member |
| <code>allocate</code> and not yet passed to member <code>deallocate</code>. |
| The value hint may be used by an implementation to help improve performance |
| <sup>223)</sup>.</del> <ins>[<i>Note:</i> The value <i>hint</i> may be used by an |
| implementation to help improve performance. -- <i>end note</i>]</ins> |
| </p> |
| <blockquote><p> |
| <del>[Footnote: <sup>223)</sup>In a container member function, the address of an |
| adjacent element is often a good choice to pass for this argument.</del> |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="581"></a>581. <code>flush()</code> not unformatted function</h3> |
| <p><b>Section:</b> 27.6.2.7 [ostream.unformatted] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-06-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.unformatted">issues</a> in [ostream.unformatted].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The resolution of issue 60 changed <code>basic_ostream::flush()</code> |
| so as not to require it to behave as an unformatted output function. |
| That has at least two in my opinion problematic consequences: |
| |
| </p> |
| <p> |
| |
| First, <code>flush()</code> now calls <code>rdbuf()->pubsync()</code> |
| unconditionally, without regard to the state of the stream. I can't |
| think of any reason why <code>flush()</code> should behave differently |
| from the vast majority of stream functions in this respect. |
| |
| </p> |
| <p> |
| |
| Second, <code>flush()</code> is not required to catch exceptions from |
| <code>pubsync()</code> or set <code>badbit</code> in response to such |
| events. That doesn't seem right either, as most other stream functions |
| do so. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to revert the resolution of issue 60 with respect to |
| <code>flush()</code>. Specifically, I propose to change 27.6.2.6, p7 |
| as follows: |
| |
| </p> |
| |
| <p> |
| Effects: <ins>Behaves as an unformatted output function (as described |
| in 27.6.2.6, paragraph 1). </ins>If <code>rdbuf()</code> is not a null |
| pointer, <ins>constructs a sentry object. If this object returns |
| <code>true</code> when converted to a value of type bool the function |
| </ins>calls <code>rdbuf()->pubsync()</code>. If that function returns |
| -1 calls <code>setstate(badbit)</code> (which may throw |
| <code>ios_base::failure</code> (27.4.4.3)). <ins>Otherwise, if the |
| sentry object returns <code>false</code>, does nothing.</ins><del>Does |
| not behave as an unformatted output function (as described in |
| 27.6.2.6, paragraph 1).</del> |
| </p> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): Proposed Disposition: Ready |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="586"></a>586. string inserter not a formatted function</h3> |
| <p><b>Section:</b> 21.3.8.9 [string.io] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-06-22</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#string.io">issues</a> in [string.io].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| Section and paragraph numbers in this paper are relative to the |
| working draft document number N2009 from 4/21/2006. |
| |
| </p> |
| |
| <p> |
| |
| The <code>basic_string</code> extractor in 21.3.7.9, p1 is clearly |
| required to behave as a formatted input function, as is the |
| <code>std::getline()</code> overload for string described in p7. |
| |
| </p> |
| <p> |
| |
| However, the <code>basic_string</code> inserter described in p5 of the |
| same section has no such requirement. This has implications on how the |
| operator responds to exceptions thrown from <code>xsputn()</code> |
| (formatted output functions are required to set <code>badbit</code> |
| and swallow the exception unless <code>badbit</code> is also set in |
| <code>exceptions()</code>; the string inserter doesn't have any such |
| requirement). |
| |
| </p> |
| <p> |
| |
| I don't see anything in the spec for the string inserter that would |
| justify requiring it to treat exceptions differently from all other |
| similar operators. (If it did, I think it should be made this explicit |
| by saying that the operator "does not behave as a formatted output |
| function" as has been made customary by the adoption of the resolution |
| of issue 60). |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| I propose to change the Effects clause in 21.3.7.9, p5, as follows: |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <i>Effects</i>: <del>Begins by constructing a sentry object k as if k |
| were constructed by typename <code>basic_ostream<charT, |
| traits>::sentry k (os)</code>. If <code>bool(k)</code> is |
| <code>true</code>, </del><ins>Behaves as a formatted output function |
| (27.6.2.5.1). After constructing a <code>sentry</code> object, if |
| this object returns <code>true</code> when converted to a value of |
| type <code>bool</code>, determines padding as described in |
| 22.2.2.2.2</ins>, then inserts the resulting sequence of characters |
| <code><i>seq</i></code> as if by calling <code>os.rdbuf()->sputn(seq , |
| n)</code>, where <code><i>n</i></code> is the larger of |
| <code>os.width()</code> and <code>str.size()</code>; then calls |
| <code>os.width(0)</code>. <del>If the call to sputn fails, calls |
| <code>os.setstate(ios_base::failbit)</code>.</del> |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| This proposed resilution assumes the resolution of issue 394 (i.e., |
| that all formatted output functions are required to set |
| <code>ios_base::badbit</code> in response to any kind of streambuf |
| failure), and implicitly assumes that a return value of |
| <code>sputn(seq, <i>n</i>)</code> other than <code><i>n</i></code> |
| indicates a failure. |
| |
| </p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="589"></a>589. Requirements on iterators of member template functions of containers</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2006-08-02</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#536">536</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| There appears to be no requirements on the InputIterators used in sequences in 23.1.1 in |
| terms of their value_type, and the requirements in 23.1.2 appear to be overly strict |
| (requires InputIterator::value_type be the same type as the container's value_type). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 23.1.1 p3: |
| </p> |
| |
| <blockquote><p> |
| In Tables 82 and 83, <tt>X</tt> denotes a sequence class, <tt>a</tt> denotes a |
| value of <tt>X</tt>, <tt>i</tt> and <tt>j</tt> denote iterators satisfying input |
| iterator requirements <ins>and refer to elements <ins>implicitly |
| convertible to</ins> <tt>value_type</tt></ins>, <tt>[i, j)</tt> denotes a valid |
| range, <tt>n</tt> denotes a value of <tt>X::size_type</tt>, <tt>p</tt> denotes a |
| valid iterator to <tt>a</tt>, <tt>q</tt> denotes a valid dereferenceable |
| iterator to <tt>a</tt>, <tt>[q1, q2)</tt> denotes a valid range in <tt>a</tt>, |
| and <tt>t</tt> denotes a value of <tt>X::value_type</tt>. |
| </p></blockquote> |
| |
| <p> |
| Change 23.1.2 p7: |
| </p> |
| |
| <blockquote><p> |
| In Table 84, <tt>X</tt> is an associative container class, <tt>a</tt> is a value |
| of <tt>X</tt>, <tt>a_uniq</tt> is a value of <tt>X</tt> when <tt>X</tt> supports |
| unique keys, and <tt>a_eq</tt> is a value of <tt>X</tt> when <tt>X</tt> supports |
| multiple keys, <tt>i</tt> and <tt>j</tt> satisfy input iterator requirements and |
| refer to elements <del>of</del> <ins>implicitly convertible to</ins> |
| <tt>value_type</tt>, <tt>[i, j)</tt> is a valid range, <tt>p</tt> is a valid |
| iterator to <tt>a</tt>, <tt>q</tt> is a valid dereferenceable iterator to |
| <tt>a</tt>, <tt>[q1, q2)</tt> is a valid range in <tt>a</tt>, <tt>t</tt> is a |
| value of <tt>X::value_type</tt>, <tt>k</tt> is a value of <tt>X::key_type</tt> |
| and <tt>c</tt> is a value of type <tt>X::key_compare</tt>. |
| </p></blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| Concepts will probably come in and rewrite this section anyway. But just in case it is |
| easy to fix this up as a safety net and as a clear statement of intent. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="593"></a>593. __STDC_CONSTANT_MACROS</h3> |
| <p><b>Section:</b> 18.3 [cstdint], TR1 8.22 [tr.c99.cstdint] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter Brown <b>Date:</b> 2006-08-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#cstdint">issues</a> in [cstdint].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Clause 18.3 of the current Working Paper (N2009) deals with the new C++ headers |
| <cstdint> and <stdint.h>. These are of course based on the C99 header |
| <stdint.h>, and were part of TR1. |
| </p> |
| |
| <p> |
| Per 18.3.1/1, these headers define a number of macros and function macros. |
| While the WP does not mention __STDC_CONSTANT_MACROS in this context, C99 |
| footnotes do mention __STDC_CONSTANT_MACROS. Further, 18.3.1/2 states that "The |
| header defines all ... macros the same as C99 subclause 7.18." |
| </p> |
| |
| <p> |
| Therefore, if I wish to have the above-referenced macros and function macros |
| defined, must I #define __STDC_CONSTANT_MACROS before I #include <cstdint>, or |
| does the C++ header define these macros/function macros unconditionally? |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To put this issue to rest for C++0X, I propose the following addition to |
| 18.3.1/2 of the Working Paper N2009: |
| </p> |
| |
| <blockquote><p> |
| [Note: The macros defined by <cstdint> are provided unconditionally: in |
| particular, the symbols __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS |
| (mentioned in C99 footnotes 219, 220, and 222) play no role in C++. --end note] |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="595"></a>595. TR1/C++0x: fabs(complex<T>) redundant / wrongly specified</h3> |
| <p><b>Section:</b> 26.3.7 [complex.value.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Stefan Große Pawig <b>Date:</b> 2006-09-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#complex.value.ops">issues</a> in [complex.value.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| TR1 introduced, in the C compatibility chapter, the function |
| fabs(complex<T>): |
| </p> |
| <blockquote><pre>----- SNIP ----- |
| 8.1.1 Synopsis [tr.c99.cmplx.syn] |
| |
| namespace std { |
| namespace tr1 { |
| [...] |
| template<class T> complex<T> fabs(const complex<T>& x); |
| } // namespace tr1 |
| } // namespace std |
| |
| [...] |
| |
| 8.1.8 Function fabs [tr.c99.cmplx.fabs] |
| |
| 1 Effects: Behaves the same as C99 function cabs, defined in |
| subclause 7.3.8.1. |
| ----- SNIP ----- |
| </pre></blockquote> |
| |
| <p> |
| The current C++0X draft document (n2009.pdf) adopted this |
| definition in chapter 26.3.1 (under the comment // 26.3.7 values) |
| and 26.3.7/7. |
| </p> |
| <p> |
| But in C99 (ISO/IEC 9899:1999 as well as the 9899:TC2 draft document |
| n1124), the referenced subclause reads |
| </p> |
| |
| <blockquote><pre>----- SNIP ----- |
| 7.3.8.1 The cabs functions |
| |
| Synopsis |
| |
| 1 #include <complex.h> |
| double cabs(double complex z); |
| float cabsf(float complex z); |
| long double cabsl(long double z); |
| |
| Description |
| |
| 2 The cabs functions compute the complex absolute value (also called |
| norm, modulus, or magnitude) of z. |
| |
| Returns |
| |
| 3 The cabs functions return the complex absolute value. |
| ----- SNIP ----- |
| </pre></blockquote> |
| |
| <p> |
| Note that the return type of the cabs*() functions is not a complex |
| type. Thus, they are equivalent to the already well established |
| template<class T> T abs(const complex<T>& x); |
| (26.2.7/2 in ISO/IEC 14882:1998, 26.3.7/2 in the current draft |
| document n2009.pdf). |
| </p> |
| <p> |
| So either the return value of fabs() is specified wrongly, or fabs() |
| does not behave the same as C99's cabs*(). |
| </p> |
| |
| <b>Possible Resolutions</b> |
| |
| <p> |
| This depends on the intention behind the introduction of fabs(). |
| </p> |
| <p> |
| If the intention was to provide a /complex/ valued function that |
| calculates the magnitude of its argument, this should be |
| explicitly specified. In TR1, the categorization under "C |
| compatibility" is definitely wrong, since C99 does not provide |
| such a complex valued function. |
| </p> |
| <p> |
| Also, it remains questionable if such a complex valued function |
| is really needed, since complex<T> supports construction and |
| assignment from real valued arguments. There is no difference |
| in observable behaviour between |
| </p> |
| <blockquote><pre> complex<double> x, y; |
| y = fabs(x); |
| complex<double> z(fabs(x)); |
| </pre></blockquote> |
| <p> |
| and |
| </p> |
| <blockquote><pre> complex<double> x, y; |
| y = abs(x); |
| complex<double> z(abs(x)); |
| </pre></blockquote> |
| <p> |
| If on the other hand the intention was to provide the intended |
| functionality of C99, fabs() should be either declared deprecated |
| or (for C++0X) removed from the standard, since the functionality |
| is already provided by the corresponding overloads of abs(). |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| Bill believes that abs() is a suitable overload. We should remove fabs(). |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change the synopsis in 26.3.1 [complex.synopsis]: |
| </p> |
| |
| <blockquote><pre><del>template<class T> complex<T> fabs(const complex<T>&);</del> |
| </pre></blockquote> |
| |
| <p> |
| Remove 26.3.7 [complex.value.ops], p7: |
| </p> |
| |
| <blockquote> |
| <pre><del>template<class T> complex<T> fabs(const complex<T>& <i>x</i>);</del> |
| </pre> |
| <blockquote> |
| <p> |
| <del>-7- <i>Effects:</i> Behaves the same as C99 function <tt>cabs</tt>, defined in subclause 7.3.8.1.</del> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): Change the return type of <tt>fabs(complex)</tt> to <tt>T</tt>. |
| Proposed Disposition: Ready |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="596"></a>596. 27.8.1.3 Table 112 omits "a+" and "a+b" modes</h3> |
| <p><b>Section:</b> 27.8.1.4 [filebuf.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thomas Plum <b>Date:</b> 2006-09-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#filebuf.members">issues</a> in [filebuf.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In testing 27.8.1.4 [filebuf.members], Table 112 (in the latest N2009 draft), we invoke |
| </p> |
| <blockquote><pre> ostr.open("somename", ios_base::out | ios_base::in | ios_base::app) |
| </pre></blockquote> |
| <p> |
| and we expect the open to fail, because out|in|app is not listed in |
| Table 92, and just before the table we see very specific words: |
| </p> |
| <blockquote><p> |
| If mode is not some combination of flags shown in the table |
| then the open fails. |
| </p></blockquote> |
| <p> |
| But the corresponding table in the C standard, 7.19.5.3, provides two |
| modes "a+" and "a+b", to which the C++ modes out|in|app and |
| out|in|app|binary would presumably apply. |
| </p> |
| <p> |
| We would like to argue that the intent of Table 112 was to match the |
| semantics of 7.19.5.3 and that the omission of "a+" and "a+b" was |
| unintentional. (Otherwise there would be valid and useful behaviors |
| available in C file I/O which are unavailable using C++, for no |
| valid functional reason.) |
| </p> |
| <p> |
| We further request that the missing modes be explicitly restored to |
| the WP, for inclusion in C++0x. |
| </p> |
| |
| <p><i>[ |
| Martin adds: |
| ]</i></p> |
| |
| |
| <p> |
| ...besides "a+" and "a+b" the C++ table is also missing a row |
| for a lone app bit which in at least two current implementation |
| as well as in Classic Iostreams corresponds to the C stdio "a" |
| mode and has been traditionally documented as implying ios::out. |
| Which means the table should also have a row for in|app meaning |
| the same thing as "a+" already proposed in the issue. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to the table "File open modes" in 27.8.1.4 [filebuf.members]: |
| </p> |
| |
| <blockquote> |
| <table border="1"> |
| <caption> File open modes</caption> |
| <tbody><tr> |
| <th colspan="5"><tt>ios_base</tt> Flag combination</th> |
| <th><tt>stdio</tt> equivalent</th> |
| </tr> |
| <tr> |
| <th><tt>binary</tt></th><th><tt>in</tt></th><th><tt>out</tt></th><th><tt>trunc</tt></th><th><tt>app</tt></th><th><tt> </tt></th> |
| </tr> |
| |
| <tr> |
| <td> </td> <td> </td> <td><tt>+</tt></td> <td> </td> <td> </td> <td><tt>"w"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td> </td> <td><tt>+</tt></td> <td> </td> <td><tt>+</tt></td> <td><tt>"a"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td> </td> <td> </td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"a"</tt></ins></td> |
| </tr> |
| <tr> |
| <td> </td> <td> </td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td><tt>"w"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td><tt>+</tt></td> <td> </td> <td> </td> <td> </td> <td><tt>"r"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td> </td> <td><tt>"r+"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td><tt>"w+"</tt></td> |
| </tr> |
| <tr> |
| <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>+</tt></ins></td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"a+"</tt></ins></td> |
| </tr> |
| <tr> |
| <td> </td> <td><ins><tt>+</tt></ins></td> <td> </td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"a+"</tt></ins></td> |
| </tr> |
| |
| <tr> |
| <td><tt>+</tt></td> <td> </td> <td><tt>+</tt></td> <td> </td> <td> </td> <td><tt>"wb"</tt></td> |
| </tr> |
| <tr> |
| <td><tt>+</tt></td> <td> </td> <td><tt>+</tt></td> <td> </td> <td><tt>+</tt></td> <td><tt>"ab"</tt></td> |
| </tr> |
| <tr> |
| <td><ins><tt>+</tt></ins></td> <td> </td> <td> </td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"ab"</tt></ins></td> |
| </tr> |
| <tr> |
| <td><tt>+</tt></td> <td> </td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td><tt>"wb"</tt></td> |
| </tr> |
| <tr> |
| <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td> </td> <td> </td> <td><tt>"rb"</tt></td> |
| </tr> |
| <tr> |
| <td><tt>+</tt></td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td> </td> <td><tt>"r+b"</tt></td> |
| </tr> |
| <tr> |
| <td><tt>+</tt></td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td><tt>+</tt></td> <td> </td> <td><tt>"w+b"</tt></td> |
| </tr><tr> |
| <td><ins><tt>+</tt></ins></td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>+</tt></ins></td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"a+b"</tt></ins></td> |
| </tr> |
| <tr> |
| <td><ins><tt>+</tt></ins></td> <td><ins><tt>+</tt></ins></td> <td> </td> <td> </td> <td><ins><tt>+</tt></ins></td> <td><ins><tt>"a+b"</tt></ins></td> |
| </tr> |
| |
| |
| </tbody></table> |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007) Added proposed wording and moved to Review. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="598"></a>598. Decimal: Conversion to integral should truncate, not round.</h3> |
| <p><b>Section:</b> TRDecimal 3.2 [trdec.types.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Daniel Krugler <b>Date:</b> 2006-05-28</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#trdec.types.types">active issues</a> in [trdec.types.types].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#trdec.types.types">issues</a> in [trdec.types.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| In a private email, Daniel writes: |
| </p> |
| <blockquote> |
| <p> |
| I would like to |
| ask, what where the reason for the decision to |
| define the semantics of the integral conversion of the decimal types, namely |
| </p> |
| <pre>"operator long long() const; |
| |
| Returns: Returns the result of the |
| conversion of *this to the type long long, as if |
| performed by the expression llrounddXX(*this)." |
| </pre> |
| <p> |
| where XX stands for either 32, 64, or 128, |
| corresponding to the proper decimal type. The |
| exact meaning of llrounddXX is not given in that |
| paper, so I compared it to the corresponding |
| definition given in C99, 2nd edition (ISO 9899), which says in 7.12.9.7 p. 2: |
| </p> |
| <p> |
| "The lround and llround functions round their |
| argument to the nearest integer value, |
| rounding halfway cases away from zero, regardless |
| of the current rounding direction. [..]" |
| </p> |
| <p> |
| Now considering the fact that integral conversion |
| of the usual floating-point types ("4.9 |
| Floating-integral conversions") has truncation |
| semantic I wonder why this conversion behaviour |
| has not been transferred for the decimal types. |
| </p> |
| </blockquote> |
| <p> |
| Robert comments: |
| </p> |
| <p> |
| Also, there is a further error in the <b>Returns:</b> clause for converting <code>decimal::decimal128</code> to <code>long long</code>. It currently calls <code>llroundd64</code>, not <code>llroundd128</code>. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.2.4 to: |
| </p> |
| <blockquote><p> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd32(*this)</code> <ins>while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </p></blockquote> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.3.4 to: |
| </p> |
| <blockquote><p> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <code>llroundd64(*this)</code> <ins>while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </p></blockquote> |
| <p> |
| Change the <b>Returns:</b> clause in 3.2.4.4 to: |
| </p> |
| <blockquote><p> |
| <b>Returns:</b> Returns the result of the conversion of <code>*this</code> to the type <code>long long</code>, as if performed by the expression <del><code>llroundd64(*this)</code></del> <ins><code>llroundd128(*this)</code> while the decimal rounding direction mode [3.5.2] <code>FE_DEC_TOWARD_ZERO</code> is in effect</ins>. |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="599"></a>599. Decimal: Say "octets" instead of "bytes."</h3> |
| <p><b>Section:</b> TRDecimal 3.1 [trdec.types.encodings] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Daniel Krugler <b>Date:</b> 2006-05-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Daniel writes in a private email: |
| </p> |
| |
| <blockquote> |
| <p> |
| - 3.1 'Decimal type encodings' says in its note: |
| </p> |
| <pre>"this implies that |
| sizeof(std::decimal::decimal32) == 4, |
| sizeof(std::decimal::decimal64) == 8, and |
| sizeof(std::decimal::decimal128) == 16." |
| </pre> |
| <p> |
| This is a wrong assertion, because the definition |
| of 'byte' in 1.7 'The C+ + memory model' of ISO |
| 14882 (2nd edition) does not specify that a byte |
| must be necessarily 8 bits large, which would be |
| necessary to compare with the specified bit sizes |
| of the types decimal32, decimal64, and decimal128. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 3.1 as follows: |
| </p> |
| <blockquote> |
| <p> |
| The three decimal encoding formats defined in IEEE-754R correspond to the three decimal floating types as follows: |
| </p> |
| <ul> |
| <li> |
| decimal32 is a <em>decimal32</em> number, which is encoded in four consecutive <del>bytes</del> <ins>octets</ins> (32 bits) |
| </li> |
| <li> |
| decimal64 is a <em>decimal64</em> number, which is encoded in eight consecutive <del>bytes</del> <ins>octets</ins> (64 bits) |
| |
| </li> |
| <li> |
| decimal128 is a <em>decimal128</em> number, which is encoded in 16 consecutive <del>bytes</del> <ins>octets</ins> (128 bits) |
| </li> |
| </ul> |
| <p> |
| <del>[<i>Note:</i> this implies that <code>sizeof(std::decimal::decimal32) == 4</code>, <code>sizeof(std::decimal::decimal64) == 8</code>, and <code>sizeof(std::decimal::decimal128) == 16</code>. <i>--end note</i>]</del> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="600"></a>600. Decimal: Wrong parameters for wcstod* functions</h3> |
| <p><b>Section:</b> TRDecimal 3.9 [trdec.types.cwchar] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Daniel Krugler <b>Date:</b> 2006-05-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Daniel writes: |
| </p> |
| <blockquote><p> |
| - 3.9.1 'Additions to <cwchar>' provides wrong |
| signatures to the wcstod32, wcstod64, and |
| wcstod128 functions ([the parameters have type pointer-to-] char instead of wchar_t). |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change "3.9.1 Additions to <code><cwchar></code> synopsis" to: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| // 3.9.2 wcstod functions: |
| decimal32 wcstod32 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| decimal64 wcstod64 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| decimal128 wcstod128 (const <del>char</del> <ins>wchar_t</ins> * nptr, <del>char</del> <ins>wchar_t</ins> ** endptr); |
| } |
| } |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="601"></a>601. Decimal: numeric_limits typos</h3> |
| <p><b>Section:</b> TRDecimal 3.3 [trdec.types.limits] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Daniel Krugler <b>Date:</b> 2006-05-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Daniel writes in a private email: |
| </p> |
| |
| <blockquote> |
| <p> |
| - 3.3 'Additions to header <limits>' contains two |
| errors in the specialisation of numeric_limits<decimal::decimal128>: |
| </p> |
| <ol> |
| <li>The static member max() returns DEC128_MIN, this should be DEC128_MAX.</li> |
| <li>The static member digits is assigned to 384, |
| this should be 34 (Probably mixed up with the |
| max. exponent for decimal::decimal64).</li> |
| </ol> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In "3.3 Additions to header <code><limits></code>" change numeric_limits<decimal::decimal128> as follows: |
| </p> |
| <pre> template<> class numeric_limits<decimal::decimal128> { |
| public: |
| static const bool is_specialized = true; |
| |
| static decimal::decimal128 min() throw() { return DEC128_MIN; } |
| static decimal::decimal128 max() throw() { return <del>DEC128_MIN;</del> <ins>DEC128_MAX;</ins> } |
| |
| static const int digits = <del>384</del> <ins>34</ins>; |
| /* ... */ |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="602"></a>602. Decimal: "generic floating type" not defined.</h3> |
| <p><b>Section:</b> TRDecimal 3 [trdec.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Daniel Krugler <b>Date:</b> 2006-05-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#trdec.types">issues</a> in [trdec.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The document uses the term "generic floating types," but defines it nowhere. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the first paragraph of "3 Decimal floating-point types" as follows: |
| </p> |
| <blockquote><p> |
| This Technical Report introduces three decimal floating-point types, named |
| decimal32, decimal64, and decimal128. The set of values of type decimal32 is a |
| subset of the set of values of type decimal64; the set of values of the type |
| decimal64 is a subset of the set of values of the type decimal128. Support for |
| decimal128 is optional. <ins>These types supplement the Standard C++ types |
| <code>float</code>, <code>double</code>, and <code>long double</code>, which are |
| collectively described as the <i>basic floating types</i></ins>. |
| </p></blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="603"></a>603. Decimal: Trivially simplifying decimal classes.</h3> |
| <p><b>Section:</b> TRDecimal 3 [trdec.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-05-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#trdec.types">issues</a> in [trdec.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>In c++std-lib-17198, Martin writes:</p> |
| |
| <blockquote><p> |
| Each of the three classes proposed in the paper (decimal32, decimal64, |
| and decimal128) explicitly declares and specifies the semantics of its |
| copy constructor, copy assignment operator, and destructor. Since the |
| semantics of all three functions are identical to the trivial versions |
| implicitly generated by the compiler in the absence of any declarations |
| it is safe to drop them from the spec. This change would make the |
| proposed classes consistent with other similar classes already in the |
| standard (e.g., std::complex). |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change "3.2.2 Class <code>decimal32</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal32 { |
| public: |
| // 3.2.2.1 construct/copy/destroy: |
| decimal32(); |
| <del>decimal32(const decimal32 & d32);</del> |
| <del>decimal32 & operator=(const decimal32 & d32);</del> |
| <del>~decimal32();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.2.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal32(); |
| |
| Effects: Constructs an object of type decimal32 with the value 0; |
| |
| <del>decimal32(const decimal32 & d32);</del> |
| <del>decimal32 & operator=(const decimal32 & d32);</del> |
| |
| <del>Effects: Copies an object of type decimal32.</del> |
| |
| <del>~decimal32();</del> |
| |
| <del>Effects: Destroys an object of type decimal32.</del> |
| |
| </pre> |
| <p> |
| Change "3.2.3 Class <code>decimal64</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal64 { |
| public: |
| // 3.2.3.1 construct/copy/destroy: |
| decimal64(); |
| <del>decimal64(const decimal64 & d64);</del> |
| <del>decimal64 & operator=(const decimal64 & d64);</del> |
| <del>~decimal64();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.3.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal64(); |
| |
| Effects: Constructs an object of type decimal64 with the value 0; |
| |
| <del>decimal64(const decimal64 & d64);</del> |
| <del>decimal64 & operator=(const decimal64 & d64);</del> |
| |
| <del>Effects: Copies an object of type decimal64.</del> |
| |
| <del>~decimal64();</del> |
| |
| <del>Effects: Destroys an object of type decimal64.</del> |
| |
| </pre> |
| <p> |
| Change "3.2.4 Class <code>decimal128</code>" as follows: |
| </p> |
| <pre> namespace std { |
| namespace decimal { |
| class decimal128 { |
| public: |
| // 3.2.4.1 construct/copy/destroy: |
| decimal128(); |
| <del>decimal128(const decimal128 & d128);</del> |
| <del>decimal128 & operator=(const decimal128 & d128);</del> |
| <del>~decimal128();</del> |
| /* ... */ |
| </pre> |
| <p> |
| Change "3.2.4.1 construct/copy/destroy" as follows: |
| </p> |
| <pre> decimal128(); |
| |
| Effects: Constructs an object of type decimal128 with the value 0; |
| |
| <del>decimal128(const decimal128 & d128);</del> |
| <del>decimal128 & operator=(const decimal128 & d128);</del> |
| |
| <del>Effects: Copies an object of type decimal128.</del> |
| |
| <del>~decimal128();</del> |
| |
| <del>Effects: Destroys an object of type decimal128.</del> |
| |
| </pre> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="604"></a>604. Decimal: Storing a reference to a facet unsafe.</h3> |
| <p><b>Section:</b> TRDecimal 3 [trdec.types] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2006-05-28</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#trdec.types">issues</a> in [trdec.types].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In c++std-lib-17197, Martin writes: |
| </p> |
| <blockquote><p> |
| The extended_num_get and extended_num_put facets are designed |
| to store a reference to a num_get or num_put facet which the |
| extended facets delegate the parsing and formatting of types |
| other than decimal. One form of the extended facet's ctor (the |
| default ctor and the size_t overload) obtains the reference |
| from the global C++ locale while the other form takes this |
| reference as an argument. |
| </p></blockquote> |
| <blockquote><p> |
| The problem with storing a reference to a facet in another |
| object (as opposed to storing the locale object in which the |
| facet is installed) is that doing so bypasses the reference |
| counting mechanism designed to prevent a facet that is still |
| being referenced (i.e., one that is still installed in some |
| locale) from being destroyed when another locale that contains |
| it is destroyed. Separating a facet reference from the locale |
| it comes from van make it cumbersome (and in some cases might |
| even make it impossible) for programs to prevent invalidating |
| the reference. (The danger of this design is highlighted in |
| the paper.) |
| </p></blockquote> |
| <blockquote><p> |
| This problem could be easily avoided by having the extended |
| facets store a copy of the locale from which they would extract |
| the base facet either at construction time or when needed. To |
| make it possible, the forms of ctors of the extended facets that |
| take a reference to the base facet would need to be changed to |
| take a locale argument instead. |
| </p></blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. Change the <code>extended_num_get</code> synopsis in 3.10.2 as follows: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| /* ... */ |
| |
| <del>// <i>const std::num_get<charT, InputIterator> & <b>base</b></i>; <i><b>exposition only</b></i></del> |
| <ins>// <i>std::locale <b>baseloc</b></i>; <i><b>exposition only</b></i></ins> |
| </pre> |
| <p> |
| 2. Change the description of the above constructor in 3.10.2.1: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| </pre> |
| <blockquote> |
| <p> |
| <b>Effects:</b> Constructs an <code>extended_num_get</code> facet as if by: |
| </p> |
| <pre> extended_num_get(const <del>std::num_get<charT, InputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0) |
| : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>) |
| { /* ... */ } |
| |
| </pre> |
| <p> |
| <del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_get</code> facet.</del> |
| </p> |
| </blockquote> |
| <p> |
| 3. Change the <b>Returns:</b> clause for <code>do_get(iter_type, iter_type, ios_base &, ios_base::iostate &, bool &) const</code>, <i>et al</i> to |
| </p> |
| <blockquote><p> |
| <b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet<std::num_get<charT, InputIterator> >(<i>baseloc</i>)</ins>.get(<i>in</i>, <i>end</i>, <i>str</i>, <i>err</i>, <i>val</i>)</code>. |
| </p></blockquote> |
| <p> |
| 4. Change the <code>extended_num_put</code> synopsis in 3.10.3 as follows: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| |
| /* ... */ |
| |
| <del>// <i>const std::num_put<charT, OutputIterator> & <b>base</b></i>; <i><b>exposition only</b></i></del> |
| <ins>// <i>std::locale <b>baseloc</b></i>; <i><b>exposition only</b></i></ins> |
| </pre> |
| <p> |
| 5. Change the description of the above constructor in 3.10.3.1: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0); |
| </pre> |
| <blockquote> |
| <p> |
| <b>Effects:</b> Constructs an <code>extended_num_put</code> facet as if by: |
| </p> |
| <pre> extended_num_put(const <del>std::num_put<charT, OutputIterator></del> <ins>std::locale</ins> & <i>b</i>, size_t <i>refs</i> = 0) |
| : facet(<i>refs</i>), <i>base<ins>loc</ins></i>(<i>b</i>) |
| { /* ... */ } |
| |
| </pre> |
| <p> |
| <del><b>Notes:</b> Care must be taken by the implementation to ensure that the lifetime of the facet referenced by <i>base</i> exceeds that of the resulting <code>extended_num_put</code> facet.</del> |
| </p> |
| </blockquote> |
| <p> |
| 6. Change the <b>Returns:</b> clause for <code>do_put(iter_type, ios_base &, char_type, bool &) const</code>, <i>et al</i> to |
| </p> |
| <blockquote><p> |
| <b>Returns:</b> <code><del><i>base</i></del> <ins>std::use_facet<std::num_put<charT, OutputIterator> >(<i>baseloc</i>)</ins>.put(<i>s</i>, <i>f</i>, <i>fill</i>, <i>val</i>)</code>. |
| </p></blockquote> |
| |
| <p><i>[ |
| Redmond: We would prefer to rename "extended" to "decimal". |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="605"></a>605. Decimal: <decfloat.h> doesn't live here anymore.</h3> |
| <p><b>Section:</b> TRDecimal 3.4 [trdec.types.cdecfloat] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#TRDec">TRDec</a> |
| <b>Submitter:</b> Robert Klarer <b>Date:</b> 2006-10-17</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#TRDec">TRDec</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In Berlin, WG14 decided to drop the <decfloat.h> header. The |
| contents of that header have been moved into <float.h>. For the |
| sake of C compatibility, we should make corresponding changes. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1. Change the heading of subclause 3.4, "Headers <code><cdecfloat></code> and <code><decfloat.h></code>" to "Additions to headers <code><cfloat></code> and <code><float.h></code>." |
| </p> |
| <p> |
| 2. Change the text of subclause 3.4 as follows: |
| </p> |
| <blockquote> |
| <p> |
| <del>The standard C++ headers <code><cfloat></code> and <code><float.h></code> define characteristics of the floating-point types <code>float</code>, <code>double</code>, and <code>long double</code>. Their contents remain unchanged by this Technical Report.</del> |
| </p> |
| <p> |
| <del>Headers <code><cdecfloat></code> and <code><decfloat.h></code> define characteristics of the decimal floating-point types <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code>. As well, <code><decfloat.h></code> defines the convenience typedefs <code>_Decimal32</code>, <code>_Decimal64</code>, and <code>_Decimal128</code>, for compatibilty with the C programming language.</del> |
| </p> |
| <p> |
| <ins>The header <code><cfloat></code> is described in [tr.c99.cfloat]. The header <code><float.h></code> |
| is described in [tr.c99.floath]. These headers are extended by this |
| Technical Report to define characteristics of the decimal |
| floating-point types <code>decimal32</code>, <code>decimal64</code>, and <code>decimal128</code>. As well, <code><float.h></code> is extended to define the convenience typedefs <code>_Decimal32</code>, <code>_Decimal64</code>, and <code>_Decimal128</code> for compatibility with the C programming language.</ins> |
| </p> |
| </blockquote> |
| <p> |
| 3. Change the heading of subclause 3.4.1, "Header <code><cdecfloat></code> synopsis" to "Additions to header <code><cfloat></code> synopsis." |
| </p> |
| <p> |
| 4. Change the heading of subclause 3.4.2, "Header <code><decfloat.h></code> synopsis" to "Additions to header <code><float.h></code> synopsis." |
| </p> |
| <p> |
| 5. Change the contents of 3.4.2 as follows: |
| </p> |
| <pre> <del>#include <cdecfloat></del> |
| |
| // <i>C-compatibility convenience typedefs:</i> |
| |
| typedef std::decimal::decimal32 _Decimal32; |
| typedef std::decimal::decimal64 _Decimal64; |
| typedef std::decimal::decimal128 _Decimal128; |
| </pre> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="607"></a>607. Concern about short seed vectors</h3> |
| <p><b>Section:</b> 26.4.7.1 [rand.util.seedseq] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Charles Karney <b>Date:</b> 2006-10-26</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Short seed vectors of 32-bit quantities all result in different states. However |
| this is not true of seed vectors of 16-bit (or smaller) quantities. For example |
| these two seeds |
| </p> |
| |
| <blockquote><pre>unsigned short seed = {1, 2, 3}; |
| unsigned short seed = {1, 2, 3, 0}; |
| </pre></blockquote> |
| |
| <p> |
| both pack to |
| </p> |
| |
| <blockquote><pre>unsigned seed = {0x20001, 0x3}; |
| </pre></blockquote> |
| |
| <p> |
| yielding the same state. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="608"></a>608. Unclear seed_seq construction details</h3> |
| <p><b>Section:</b> 26.4.7.1 [rand.util.seedseq] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Charles Karney <b>Date:</b> 2006-10-26</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 26.4.7.1 [rand.util.seedseq] /6, the order of packing the inputs into b and the |
| treatment of signed quantities is unclear. Better to spell it out. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="609"></a>609. missing static const</h3> |
| <p><b>Section:</b> 26.4.4.2 [rand.adapt.ibits], TR1 5.1 [tr.rand] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Walter E. Brown <b>Date:</b> 2006-11-02</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In preparing N2111, an error on my part resulted in the omission of the |
| following line from the template synopsis in the cited section: |
| </p> |
| |
| <blockquote><pre>static const size_t word_size = w; |
| </pre></blockquote> |
| |
| <p> |
| (This same constant is found, for example, in 26.4.3.3 [rand.eng.sub].) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the above declaration as the first line after the comment in [rand.adapt.ibits] p4: |
| </p> |
| |
| <blockquote><pre>// engine characteristics |
| <ins>static const size_t word_size = w;</ins> |
| </pre></blockquote> |
| |
| <p> |
| and accept my apologies for the oversight. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="610"></a>610. Suggested non-normative note for C++0x</h3> |
| <p><b>Section:</b> 20.6.15.2.1 [func.wrap.func.con], TR1 3.7.2.1 [tr.func.wrap.func.con] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Scott Meyers <b>Date:</b> 2006-11-02</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| My suggestion is that implementers of both tr1::function and its |
| official C++0x successor be explicitly encouraged (but not required) to |
| optimize for the cases mentioned above, i.e., function pointers and |
| small function objects. They could do this by using a small internal |
| buffer akin to the buffer used by implementations of the small string |
| optimization. (That would make this the small functor optimization -- |
| SFO :-}) The form of this encouragement could be a note in the standard |
| akin to footnote 214 of the current standard. |
| </p> |
| |
| <p> |
| Dave Abrahams notes: |
| </p> |
| |
| <p> |
| "shall not throw exceptions" should really be "nothing," both to be more |
| grammatical and to be consistent with existing wording in the standard. |
| </p> |
| |
| <p> |
| Doug Gregor comments: I think this is a good idea. Currently, implementations of |
| tr1::function are required to have non-throwing constructors and assignment |
| operators when the target function object is a function pointer or a |
| reference_wrapper. The common case, however, is for a tr1::function to store |
| either an empty function object or a member pointer + an object pointer. |
| </p> |
| <p> |
| The function implementation in the upcoming Boost 1.34.0 uses the |
| "SFO", so that the function objects for typical bind expressions like |
| </p> |
| <blockquote><pre>bind(&X::f, this, _1, _2, _3) |
| </pre></blockquote> |
| |
| <p> |
| do not require heap allocation when stored in a boost::function. I |
| believe Dinkumware's implementation also performs this optimization. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Revise 20.5.14.2.1 p6 [func.wrap.func.con] to add a note as follows: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Throws:</i> shall not throw exceptions if <tt>f</tt>'s target is a function |
| pointer or a function object passed via <tt>reference_wrapper</tt>. Otherwise, |
| may throw <tt>bad_alloc</tt> or any exception thrown by the copy constructor of |
| the stored function object. |
| </p> |
| <p> |
| <ins><i>Note:</i> Implementations are encouraged to avoid the use of dynamically |
| allocated memory for "small" function objects, e.g., where <tt>f</tt>'s target |
| is an object holding only a pointer or reference to an object and a member |
| function pointer (a "bound member function").</ins> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="611"></a>611. Standard library templates and incomplete types</h3> |
| <p><b>Section:</b> 17.4.3.7 [res.on.functions] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nicola Musatti <b>Date:</b> 2006-11-13</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the latest available draft standard |
| (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2134.pdf">N2134</a>) |
| § 17.4.3.6 [res.on.functions] states: |
| </p> |
| |
| <blockquote> |
| <p> |
| -1- In certain cases (replacement functions, handler functions, operations on |
| types used to instantiate standard library template components), the C++ |
| Standard Library depends on components supplied by a C++ program. If these |
| components do not meet their requirements, the Standard places no requirements |
| on the implementation. |
| </p> |
| |
| <p> |
| -2- In particular, the effects are undefined in the following cases: |
| </p> |
| <p> |
| [...] |
| </p> |
| <ul> |
| <li>if an incomplete type (3.9) is used as a template argument when |
| instantiating a template component. </li> |
| </ul> |
| </blockquote> |
| |
| <p> |
| This is contradicted by § 20.6.6.2/2 [util.smartptr.shared] which |
| states: |
| </p> |
| |
| <blockquote> |
| <p> |
| [...] |
| </p> |
| |
| <p> |
| The template parameter <tt>T</tt> of <tt>shared_ptr</tt> may be an incomplete type. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Modify the last bullet of § 17.4.3.6/2 [res.on.functions] to allow for |
| exceptions: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li>if an incomplete type (3.9) is used as a template argument when |
| instantiating a template component<ins>, unless specifically allowed for the |
| component</ins>. </li> |
| </ul> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="612"></a>612. numeric_limits::is_modulo insufficiently defined</h3> |
| <p><b>Section:</b> 18.2.1.2 [numeric.limits.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Chris Jefferson <b>Date:</b> 2006-11-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#numeric.limits.members">issues</a> in [numeric.limits.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 18.2.1.2 55 states that "A type is modulo if it is possible to add two |
| positive numbers together and have a result that wraps around to a |
| third number that is less". |
| This seems insufficient for the following reasons: |
| </p> |
| |
| <ol> |
| <li>Doesn't define what that value received is.</li> |
| <li>Doesn't state the result is repeatable</li> |
| <li> Doesn't require that doing addition, subtraction and other |
| operations on all values is defined behaviour.</li> |
| </ol> |
| |
| <p><i>[ |
| Batavia: Related to |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2144.pdf">N2144</a>. |
| Pete: is there an ISO definition of modulo? Underflow on signed behavior is undefined. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Bellevue: accept resolution, move to ready status. |
| Does this mandate that is_modulo be true on platforms for which int |
| happens to b modulo? A: the standard already seems to require that. |
| ]</i></p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Suggest 18.2.1.2 [numeric.limits.members], paragraph 57 is amended to: |
| </p> |
| |
| <blockquote><p> |
| A type is modulo if<ins>,</ins> <del>it is possible to add two positive numbers |
| and have a result that wraps around to a third number that is less.</del> |
| <ins>given any operation involving +,- or * on values of that type whose value |
| would fall outside the range <tt>[min(), max()]</tt>, then the value returned |
| differs from the true value by an integer multiple of <tt>(max() - min() + |
| 1)</tt>.</ins> |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="613"></a>613. max_digits10 missing from numeric_limits</h3> |
| <p><b>Section:</b> 18.2.1.5 [numeric.special] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bo Persson <b>Date:</b> 2006-11-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#numeric.special">issues</a> in [numeric.special].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 18.2.1.5 [numeric.special] starts out by saying that "All members shall be provided |
| for all specializations." |
| </p> |
| <p> |
| Then it goes on to show specializations for float and bool, where one member |
| is missing (max_digits10). |
| </p> |
| |
| <p> |
| Maarten Kronenburg adds: |
| </p> |
| |
| <p> |
| I agree, just adding the comment that the exact number of decimal digits |
| is digits * ln(radix) / ln(10), where probably this real number is |
| rounded downward for digits10, and rounded upward for max_digits10 |
| (when radix=10, then digits10=max_digits10). |
| Why not add this exact definition also to the standard, so the user |
| knows what these numbers exactly mean. |
| </p> |
| |
| <p> |
| Howard adds: |
| </p> |
| |
| <p> |
| For reference, here are the correct formulas from |
| <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf">N1822</a>: |
| </p> |
| |
| <blockquote><pre>digits10 = floor((digits-1) * log10(2)) |
| max_digits10 = ceil((1 + digits) * log10(2)) |
| </pre></blockquote> |
| |
| <p> |
| We are also missing a statement regarding for what specializations this member has meaning. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change and add after 18.2.1.2 [numeric.limits.members], p11: |
| </p> |
| |
| <blockquote> |
| <pre>static const int max_digits10;</pre> |
| <blockquote> |
| <p> |
| -11- Number of base 10 digits required to ensure that values which |
| differ <del>by only one epsilon</del> are always differentiated. |
| </p> |
| <p><ins> |
| -12- Meaningful for all floating point types. |
| </ins></p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Change 18.2.1.5 [numeric.special], p2: |
| </p> |
| |
| <blockquote><pre>template<> class numeric_limits<float> { |
| public: |
| static const bool is_specialized = true; |
| ... |
| static const int digits10 = 6; |
| <ins>static const int max_digits10 = 9</ins>; |
| ... |
| </pre></blockquote> |
| |
| <p> |
| Change 18.2.1.5 [numeric.special], p3: |
| </p> |
| |
| <blockquote><pre>template<> class numeric_limits<bool> { |
| public: |
| static const bool is_specialized = true; |
| ... |
| static const int digits10 = 0; |
| <ins>static const int max_digits10 = 0</ins>; |
| ... |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="616"></a>616. missing 'typename' in ctype_byname</h3> |
| <p><b>Section:</b> 22.2.1.2 [locale.ctype.byname] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bo Persson <b>Date:</b> 2006-12-16</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.ctype.byname">issues</a> in [locale.ctype.byname].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 22.2.1.2 defines the ctype_byname class template. It contains the |
| line |
| </p> |
| |
| <blockquote><pre>typedef ctype<charT>::mask mask; |
| </pre></blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| as this is a dependent type, it should obviously be |
| </p> |
| |
| <blockquote><pre>typedef <ins>typename</ins> ctype<charT>::mask mask; |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="618"></a>618. valarray::cshift() effects on empty array</h3> |
| <p><b>Section:</b> 26.5.2.7 [valarray.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Gabriel Dos Reis <b>Date:</b> 2007-01-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I would respectfully request an issue be opened with the intention to |
| clarify the wording for <tt>size() == 0</tt> for <tt>cshift</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.5.2.7 [valarray.members], paragraph 10: |
| </p> |
| |
| <blockquote> |
| |
| <pre>valarray<T> cshift(int <i>n</i>) const; |
| </pre> |
| |
| <blockquote> |
| <p> |
| This function returns an object of class <tt>valarray<T></tt>, of |
| length <tt>size()</tt>, <del>each of whose elements <tt>I</tt> is |
| <tt>(*this)[(I + n ) % size()]</tt>. Thus, if element zero is taken as |
| the leftmost element, a positive value of <i>n</i> shifts the elements |
| circularly left <i>n</i> places.</del> <ins>that is a circular shift of <tt>*this</tt>. If |
| element zero is taken as the leftmost element, a non-negative value of |
| <i>n</i> shifts the elements circularly left <i>n</i> places and a |
| negative value of <i>n</i> shifts the elements circularly right |
| -<i>n</i> places.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| <p><b>Rationale:</b></p> |
| <p> |
| We do not believe that there is any real ambiguity about what happens |
| when <tt>size() == 0</tt>, but we do believe that spelling this out as a C++ |
| expression causes more trouble that it solves. The expression is |
| certainly wrong when <tt>n < 0</tt>, since the sign of % with negative arguments |
| is implementation defined. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007) Changed proposed wording, added rationale and set to Review. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="619"></a>619. Longjmp wording problem</h3> |
| <p><b>Section:</b> 18.9 [support.runtime] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Lawrence Crowl <b>Date:</b> 2007-01-12</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The wording for <tt>longjmp</tt> is confusing. |
| </p> |
| <p> |
| 18.9 [support.runtime] -4- Other runtime support |
| </p> |
| <blockquote><p> |
| The function signature <tt>longjmp(jmp_buf jbuf, int val)</tt> has more restricted |
| behavior in this International Standard. If any automatic objects would |
| be destroyed by a thrown exception transferring control to another |
| (destination) point in the program, then a call to <tt>longjmp(jbuf, val)</tt> that |
| the throw point that transfers control to the same (destination) point has |
| undefined behavior. |
| </p></blockquote> |
| <p> |
| Someone at Google thinks that should say "then a call to <tt>longjmp(jbuf, val)</tt> |
| *at* the throw point that transfers control". |
| </p> |
| <p> |
| Bill Gibbons thinks it should say something like "If any automatic objects |
| would be destroyed by an exception thrown at the point of the longjmp and |
| caught only at the point of the setjmp, the behavior is undefined." |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In general, accept Bill Gibbons' recommendation, |
| but add "call" to indicate that the undefined behavior |
| comes from the dynamic call, not from its presence in the code. |
| In 18.9 [support.runtime] paragraph 4, change |
| </p> |
| |
| <blockquote><p> |
| The function signature <tt>longjmp(jmp_buf jbuf, int val)</tt> has more |
| restricted behavior in this International Standard. <del>If any automatic |
| objects would be destroyed by a thrown exception transferring control to another |
| (destination) point in the program, then a call to <tt>longjmp(jbuf, val)</tt> |
| that the throw point that transfers control to the same (destination) point has |
| undefined behavior.</del> <ins>A <tt>setjmp</tt>/<tt>longjmp</tt> call pair has |
| undefined behavior if replacing the <tt>setjmp</tt> and <tt>longjmp</tt> by |
| <tt>catch</tt> and <tt>throw</tt> would destroy any automatic objects.</ins> |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="620"></a>620. valid uses of empty valarrays</h3> |
| <p><b>Section:</b> 26.5.2.1 [valarray.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-01-20</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#valarray.cons">active issues</a> in [valarray.cons].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#valarray.cons">issues</a> in [valarray.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The <i>Effects</i> clause for the default <code>valarray</code> ctor |
| suggests that it is possible to increase the size of an empty |
| <code>valarray</code> object by calling other non-const member |
| functions of the class besides <code>resize()</code>. However, such an |
| interpretation would be contradicted by the requirement on the copy |
| assignment operator (and apparently also that on the computed |
| assignments) that the assigned arrays be the same size. See the |
| reflector discussion starting with c++std-lib-17871. |
| |
| </p> |
| <p> |
| |
| In addition, <i>Footnote</i> 280 uses some questionable normative |
| language. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Reword the <i>Effects</i> clause and <i>Footnote 280</i> as follows (26.5.2.1 [valarray.cons]): |
| |
| </p> |
| <blockquote> |
| <p> |
| |
| <code>valarray();</code> |
| |
| </p> |
| <p> |
| |
| <i>Effects</i>: Constructs an object of class |
| <code>valarray<T></code>,<sup>279)</sup> which has zero |
| length<del> until it is passed into a library function as a modifiable |
| lvalue or through a non-constant this pointer</del>.<sup>280)</sup> |
| |
| </p> |
| <p> |
| |
| <ins><i>Postcondition</i>: <code>size() == 0</code>.</ins> |
| |
| </p> |
| <p> |
| |
| <i>Footnote 280</i>: This default constructor is essential, since |
| arrays of <code>valarray</code> <del>are likely to prove useful. |
| There shall also be a way to change the size of an array after |
| initialization; this is supplied by the semantics</del> <ins>may be |
| useful. The length of an empty array can be increased after |
| initialization by means</ins> of the <code>resize()</code> member |
| function. |
| |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="621"></a>621. non-const copy assignment operators of helper arrays</h3> |
| <p><b>Section:</b> 26.5 [numarray] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-01-20</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#numarray">issues</a> in [numarray].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The computed and "fill" assignment operators of <code>valarray</code> |
| helper array class templates (<code>slice_array</code>, |
| <code>gslice_array</code>, <code>mask_array</code>, and |
| <code>indirect_array</code>) are const member functions of each class |
| template (the latter by the resolution of <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#123">123</a> |
| since they have reference semantics and thus do not affect |
| the state of the object on which they are called. However, the copy |
| assignment operators of these class templates, which also have |
| reference semantics, are non-const. The absence of constness opens |
| the door to speculation about whether they really are intended to have |
| reference semantics (existing implementations vary widely). |
| |
| </p> |
| |
| <p> |
| Pre-Kona, Martin adds: |
| </p> |
| |
| <p> |
| I realized that adding the const qualifier to the |
| functions as I suggested would break the const correctness of the |
| classes. A few possible solutions come to mind: |
| </p> |
| |
| <ol> |
| <li>Add the const qualifier to the return types of these functions.</li> |
| <li>Change the return type of all the functions to void to match |
| the signatures of all the other assignment operators these classes |
| define.</li> |
| <li>Prohibit the copy assignment of these classes by declaring the |
| copy assignment operators private (as is done and documented by |
| some implementations).</li> |
| </ol> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| Declare the copy assignment operators of all four helper array |
| class templates const. |
| |
| </p> |
| <p> |
| |
| Specifically, make the following edits: |
| |
| </p> |
| <p> |
| |
| Change the signature in 26.5.5 [template.slice.array] and |
| 26.5.5.1 [slice.arr.assign] as follows: |
| |
| </p> |
| <blockquote><pre> |
| <code><ins>const</ins> slice_array& operator= (const slice_array&)<ins> const</ins>;</code> |
| |
| </pre></blockquote> |
| <p> |
| |
| Change the signature in 26.5.7 [template.gslice.array] and |
| 26.5.7.1 [gslice.array.assign] as follows: |
| |
| </p> |
| <blockquote><pre> |
| <code><ins>const</ins> gslice_array& operator= (const gslice_array&)<ins> const</ins>;</code> |
| |
| </pre></blockquote> |
| <p> |
| |
| Change the signature in 26.5.8 [template.mask.array] and 26.5.8.1 [mask.array.assign] as |
| follows: |
| |
| </p> |
| <blockquote><pre> |
| <code><ins>const</ins> mask_array& operator= (const mask_array&)<ins> const</ins>;</code> |
| |
| </pre></blockquote> |
| <p> |
| |
| Change the signature in 26.5.9 [template.indirect.array] and |
| 26.5.9.1 [indirect.array.assign] as follows: |
| |
| </p> |
| <blockquote><pre> |
| <code><ins>const</ins> indirect_array& operator= (const indirect_array&)<ins> const</ins>;</code> |
| |
| </pre></blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007) Added const qualification to the return types and set to Ready. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="622"></a>622. behavior of <code>filebuf</code> dtor and <code>close</code> on error</h3> |
| <p><b>Section:</b> 27.8.1.17 [fstream.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-01-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| <code>basic_filebuf</code> dtor is specified to have the following |
| straightforward effects: |
| |
| </p> |
| <blockquote><p> |
| |
| <i>Effects</i>: Destroys an object of class |
| <code>basic_filebuf</code>. Calls <code>close()</code>. |
| |
| </p></blockquote> |
| <p> |
| |
| <code>close()</code> does a lot of potentially complicated processing, |
| including calling <code>overflow()</code> to write out the termination |
| sequence (to bring the output sequence to its initial shift |
| state). Since any of the functions called during the processing can |
| throw an exception, what should the effects of an exception be on the |
| dtor? Should the dtor catch and swallow it or should it propagate it |
| to the caller? The text doesn't seem to provide any guidance in this |
| regard other than the general restriction on throwing (but not |
| propagating) exceptions from destructors of library classes in |
| 17.4.4.9 [res.on.exception.handling]. |
| |
| </p> |
| <p> |
| |
| Further, the last thing <code>close()</code> is specified to do is |
| call <code>fclose()</code> to close the <code>FILE</code> pointer. The |
| last sentence of the <i>Effects</i> clause reads: |
| |
| </p> |
| <blockquote><p> |
| |
| ... If any of the calls to <code>overflow</code> or |
| <code>std::fclose</code> fails then <code>close</code> fails. |
| |
| </p></blockquote> |
| <p> |
| |
| This suggests that <code>close()</code> might be required to call |
| <code>fclose()</code> if and only if none of the calls to |
| <code>overflow()</code> fails, and avoid closing the <code>FILE</code> |
| otherwise. This way, if <code>overflow()</code> failed to flush out |
| the data, the caller would have the opportunity to try to flush it |
| again (perhaps after trying to deal with whatever problem may have |
| caused the failure), rather than losing it outright. |
| |
| </p> |
| <p> |
| |
| On the other hand, the function's <i>Postcondition</i> specifies that |
| <code>is_open() == false</code>, which suggests that it should call |
| <code>fclose()</code> unconditionally. However, since |
| <i>Postcondition</i> clauses are specified for many functions in the |
| standard, including constructors where they obviously cannot apply |
| after an exception, it's not clear whether this <i>Postcondition</i> |
| clause is intended to apply even after an exception. |
| |
| </p> |
| <p> |
| |
| It might be worth noting that the traditional behavior (Classic |
| Iostreams <code>fstream::close()</code> and C <code>fclose()</code>) |
| is to close the <code>FILE</code> unconditionally, regardless of |
| errors. |
| |
| </p> |
| |
| <p><i>[ |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#397">397</a> and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#418">418</a> for related issues. |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| After discussing this on the reflector (see the thread starting with |
| c++std-lib-17650) we propose that <code>close()</code> be clarified to |
| match the traditional behavior, that is to close the <code>FILE</code> |
| unconditionally, even after errors or exceptions. In addition, we |
| propose the dtor description be amended so as to explicitly require it |
| to catch and swallow any exceptions thrown by <code>close()</code>. |
| |
| </p> |
| <p> |
| |
| Specifically, we propose to make the following edits in |
| 27.8.1.4 [filebuf.members]: |
| |
| </p> |
| <blockquote> |
| <pre> |
| <code>basic_filebuf<charT,traits>* close();</code> |
| |
| </pre> |
| <p> |
| |
| <i>Effects</i>: If <code>is_open() == false</code>, returns a null |
| pointer. If a put area exists, calls |
| <code>overflow(traits::eof())</code> to flush characters. If the last |
| virtual member function called on <code>*this</code> (between |
| <code>underflow</code>, <code>overflow</code>, <code>seekoff</code>, |
| and <code>seekpos</code>) was <code>overflow</code> then calls |
| <code>a_codecvt.unshift</code> (possibly several times) to determine a |
| termination sequence, inserts those characters and calls |
| <code>overflow(traits::eof())</code> again. Finally<ins>, regardless |
| of whether any of the preceding calls fails or throws an exception, |
| the function</ins> <del>it</del> closes the file ("as if" by calling |
| <code>std::fclose(file)</code>).<sup>334)</sup> If any of the calls |
| <ins>made by the function</ins><del>to <code>overflow</code> |
| or</del><ins>, including </ins><code>std::fclose</code><ins>, </ins> |
| fails then <code>close</code> fails<ins> by returning a null pointer. |
| If one of these calls throws an exception, the exception is caught and |
| rethrown after closing the file.</ins> |
| |
| </p> |
| </blockquote> |
| <p> |
| |
| And to make the following edits in 27.8.1.2 [filebuf.cons]. |
| |
| </p> |
| <blockquote> |
| <pre> |
| <code>virtual ~basic_filebuf();</code> |
| |
| </pre> |
| <p> |
| |
| <i>Effects</i>: Destroys an object of class |
| <code>basic_filebuf<charT,traits></code>. Calls |
| <code>close()</code>. <ins>If an exception occurs during the |
| destruction of the object, including the call to <code>close()</code>, |
| the exception is caught but not rethrown (see |
| 17.4.4.9 [res.on.exception.handling]).</ins> |
| |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="623"></a>623. <code>pubimbue</code> forbidden to call <code>imbue</code></h3> |
| <p><b>Section:</b> 27.1.1 [iostream.limits.imbue] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-01-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| 27.1.1 [iostream.limits.imbue] specifies that "no function described in |
| clause 27 except for <code>ios_base::imbue</code> causes any instance |
| of <code>basic_ios::imbue</code> or |
| <code>basic_streambuf::imbue</code> to be called." |
| |
| </p> |
| <p> |
| |
| That contradicts the <i>Effects</i> clause for |
| <code>basic_streambuf::pubimbue()</code> which requires the function |
| to do just that: call <code>basic_streambuf::imbue()</code>. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| |
| To fix this, rephrase the sentence above to allow |
| <code>pubimbue</code> to do what it was designed to do. Specifically. |
| change 27.1.1 [iostream.limits.imbue], p1 to read: |
| |
| </p> |
| <blockquote><p> |
| |
| No function described in clause 27 except for |
| <code>ios_base::imbue</code> <ins>and <code>basic_filebuf::pubimbue</code></ins> |
| causes any instance of <code>basic_ios::imbue</code> or |
| <code>basic_streambuf::imbue</code> to be called. ... |
| |
| </p></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="624"></a>624. <code>valarray</code> assignment and arrays of unequal length</h3> |
| <p><b>Section:</b> 26.5.2.2 [valarray.assign] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-01-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| |
| The behavior of the <code>valarray</code> copy assignment operator is |
| defined only when both sides have the same number of elements and the |
| spec is explicit about assignments of arrays of unequal lengths having |
| undefined behavior. |
| |
| </p> |
| <p> |
| |
| However, the generalized subscripting assignment operators overloaded |
| on <code>slice_array</code> et al (26.5.2.2 [valarray.assign]) don't have any |
| such restriction, leading the reader to believe that the behavior of |
| these overloads is well defined regardless of the lengths of the |
| arguments. |
| |
| </p> |
| <p> |
| |
| For example, based on the reading of the spec the behavior of the |
| snippet below can be expected to be well-defined: |
| |
| </p> |
| <pre> const std::slice from_0_to_3 (0, 3, 1); // refers to elements 0, 1, 2 |
| const std::valarray<int> a (1, 3); // a = { 1, 1, 1 } |
| std::valarray<int> b (2, 4); // b = { 2, 2, 2, 2 } |
| |
| b = a [from_0_to_3]; |
| </pre> |
| <p> |
| |
| In practice, <code>b</code> may end up being <code>{ 1, 1, 1 }</code>, |
| <code>{ 1, 1, 1, 2 }</code>, or anything else, indicating that |
| existing implementations vary. |
| |
| </p> |
| |
| <p> |
| Quoting from Section 3.4, Assignment operators, of Al Vermeulen's |
| Proposal for Standard C++ Array Classes (see c++std-lib-704; |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0308.asc">N0308</a>): |
| </p> |
| <blockquote><p> |
| ...if the size of the array on the right hand side of the equal |
| sign differs from the size of the array on the left, a run time |
| error occurs. How this error is handled is implementation |
| dependent; for compilers which support it, throwing an exception |
| would be reasonable. |
| </p></blockquote> |
| |
| <p> |
| And see more history in |
| <a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/1993/N0280.pdf">N0280</a>. |
| </p> |
| |
| <p> |
| |
| It has been argued in discussions on the committee's reflector that |
| the semantics of all <code>valarray</code> assignment operators should |
| be permitted to be undefined unless the length of the arrays being |
| assigned is the same as the length of the one being assigned from. See |
| the thread starting at c++std-lib-17786. |
| |
| </p> |
| <p> |
| |
| In order to reflect such views, the standard must specify that the |
| size of the array referred to by the argument of the assignment must |
| match the size of the array under assignment, for example by adding a |
| <i>Requires</i> clause to 26.5.2.2 [valarray.assign] as follows: |
| |
| </p> |
| <blockquote><p> |
| |
| <i>Requires</i>: The length of the array to which the argument refers |
| equals <code>size()</code>. |
| |
| </p></blockquote> |
| |
| <p> |
| |
| Note that it's far from clear that such leeway is necessary in order |
| to implement <code>valarray</code> efficiently. |
| |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Insert new paragraph into 26.5.2.2 [valarray.assign]: |
| </p> |
| |
| <blockquote> |
| <pre>valarray<T>& operator=(const slice_array<T>&); |
| valarray<T>& operator=(const gslice_array<T>&); |
| valarray<T>& operator=(const mask_array<T>&); |
| valarray<T>& operator=(const indirect_array<T>&); |
| </pre> |
| <blockquote> |
| <p><ins> |
| <i>Requires</i>: The length of the array to which the argument refers |
| equals <code>size()</code>. |
| </ins></p> |
| <p> |
| These operators allow the results of a generalized subscripting operation to be assigned directly to a <tt>valarray</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="628"></a>628. Inconsistent definition of basic_regex constructor</h3> |
| <p><b>Section:</b> 28.8 [re.regex] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bo Persson <b>Date:</b> 2007-01-23</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#re.regex">issues</a> in [re.regex].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 28.8 [re.regex] lists a constructor |
| </p> |
| |
| <blockquote><pre>template<class InputIterator> |
| basic_regex(InputIterator first, InputIterator last, |
| flag_type f = regex_constants::ECMAScript); |
| </pre></blockquote> |
| |
| <p> |
| However, in section 28.8.2 [re.regex.construct], this constructor takes a |
| pair of <tt>ForwardIterator</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 28.8.2 [re.regex.construct]: |
| </p> |
| |
| <blockquote><pre>template <class <del>ForwardIterator</del> <ins>InputIterator</ins>> |
| basic_regex(<del>ForwardIterator</del> <ins>InputIterator</ins> first, <del>ForwardIterator</del> <ins>InputIterator</ins> last, |
| flag_type f = regex_constants::ECMAScript); |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="634"></a>634. <tt>allocator.address()</tt> doesn't work for types overloading <tt>operator&</tt></h3> |
| <p><b>Section:</b> 20.7.5.1 [allocator.members] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-02-07</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#allocator.members">issues</a> in [allocator.members].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#350">350</a></p> |
| <p><b>Discussion:</b></p> |
| |
| <p> |
| 20.7.5.1 [allocator.members] says: |
| </p> |
| <blockquote> |
| <pre>pointer address(reference <i>x</i>) const;</pre> |
| <blockquote> |
| <p> |
| -1- <i>Returns:</i> <tt>&<i>x</i></tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| 20.7.5.1 [allocator.members] defines <tt>CopyConstructible</tt> which currently not |
| only defines the semantics of copy construction, but also restricts what an overloaded |
| <tt>operator&</tt> may do. I believe proposals are in the works (such as concepts |
| and rvalue reference) to decouple these two requirements. Indeed it is not evident |
| that we should disallow overloading <tt>operator&</tt> to return something other |
| than the address of <tt>*this</tt>. |
| </p> |
| |
| <p> |
| An example of when you want to overload <tt>operator&</tt> to return something |
| other than the object's address is proxy references such as <tt>vector<bool></tt> |
| (or its replacement, currently code-named <tt>bit_vector</tt>). Taking the address of |
| such a proxy reference should logically yield a proxy pointer, which when dereferenced, |
| yields a copy of the original proxy reference again. |
| </p> |
| |
| <p> |
| On the other hand, some code truly needs the address of an object, and not a proxy |
| (typically for determining the identity of an object compared to a reference object). |
| <a href="http://www.boost.org/">boost</a> has long recognized this dilemma and solved it with |
| <a href="http://www.boost.org/libs/utility/utility.htm#addressof"><tt>boost::addressof</tt></a>. |
| It appears to me that this would be useful functionality for the default allocator. Adopting |
| this definition for <tt>allocator::address</tt> would free the standard of requiring |
| anything special from types which overload <tt>operator&</tt>. Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#580">580</a> |
| is expected to make use of <tt>allocator::address</tt> mandatory for containers. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 20.7.5.1 [allocator.members]: |
| </p> |
| |
| <blockquote> |
| <pre>pointer address(reference <i>x</i>) const;</pre> |
| <blockquote> |
| <p> |
| -1- <i>Returns:</i> <del><tt>&<i>x</i></tt>.</del> <ins>The actual address of object referenced by <i>x</i>, |
| even in the presence of an overloaded <tt>operator&</tt>.</ins> |
| </p> |
| </blockquote> |
| |
| <pre>const_pointer address(address(const_reference <i>x</i>) const;</pre> |
| <blockquote> |
| <p> |
| -2- <i>Returns:</i> <del><tt>&<i>x</i></tt>.</del> <ins>The actual address of object referenced by <i>x</i>, |
| even in the presence of an overloaded <tt>operator&</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[ |
| post Oxford: This would be rendered NAD Editorial by acceptance of |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2257.html">N2257</a>. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2387 for this issue which |
| was subsequently split out into a separate paper N2436 for the purposes of voting. |
| The resolution in N2436 addresses this issue. The LWG voted to accelerate this |
| issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="638"></a>638. deque end invalidation during erase</h3> |
| <p><b>Section:</b> 23.2.2.3 [deque.modifiers] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Steve LoBasso <b>Date:</b> 2007-02-17</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The standard states at 23.2.2.3 [deque.modifiers]/4: |
| </p> |
| <blockquote><pre>deque erase(...) |
| </pre> |
| <p> |
| <i>Effects:</i> ... An erase at either end of the deque invalidates only |
| the iterators and the references to the erased elements. |
| </p> |
| </blockquote> |
| <p> |
| This does not state that iterators to end will be invalidated. |
| It needs to be amended in such a way as to account for end invalidation. |
| </p> |
| <p> |
| Something like: |
| </p> |
| <blockquote><p> |
| Any time the last element is erased, iterators to end are invalidated. |
| </p></blockquote> |
| |
| <p> |
| This would handle situations like: |
| </p> |
| <blockquote><pre>erase(begin(), end()) |
| erase(end() - 1) |
| pop_back() |
| resize(n, ...) where n < size() |
| pop_front() with size() == 1 |
| |
| </pre></blockquote> |
| |
| <p><i>[ |
| Post Kona, Steve LoBasso notes: |
| ]</i></p> |
| |
| |
| <blockquote> |
| My only issue with the proposed resolution is that it might not be clear |
| that <tt>pop_front()</tt> [where <tt>size() == 1</tt>] can invalidate past-the-end |
| iterators. |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 23.2.2.3 [deque.modifiers], p4: |
| </p> |
| |
| <blockquote> |
| <pre>iterator erase(const_iterator position); |
| iterator erase(const_iterator first, const_iterator last); |
| </pre> |
| |
| <blockquote> |
| <p> |
| -4- <i>Effects:</i> An erase in the middle of the <tt>deque</tt> |
| invalidates all the iterators and references to elements of the |
| <tt>deque</tt> <ins>and the past-the-end iterator</ins>. An erase at |
| either end of the <tt>deque</tt> invalidates only the iterators and the |
| references to the erased elements<ins>, except that erasing at the end |
| also invalidates the past-the-end iterator</ins>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): Proposed wording added and moved to Review. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| Note that there is existing code that relies on iterators not being |
| invalidated, but there are also existing implementations that do |
| invalidate iterators. Thus, such code is not portable in any case. There |
| is a pop_front() note, which should possibly be a separate issue. Mike |
| Spertus to evaluate and, if need be, file an issue. |
| </blockquote> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="640"></a>640. 27.6.2.5.2 does not handle (unsigned) long long</h3> |
| <p><b>Section:</b> 27.6.2.6.2 [ostream.inserters.arithmetic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-02-17</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#ostream.inserters.arithmetic">issues</a> in [ostream.inserters.arithmetic].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The arithmetic inserters are described in 27.6.2.6.2 [ostream.inserters.arithmetic]. |
| Although the section starts with a listing of the inserters including |
| the new ones: |
| </p> |
| |
| <blockquote><pre>operator<<(long long val ); |
| operator<<(unsigned long long val ); |
| </pre></blockquote> |
| |
| <p> |
| the text in paragraph 1, which describes the corresponding effects |
| of the inserters, depending on the actual type of val, does not |
| handle the types <tt>long long</tt> and <tt>unsigned long long</tt>. |
| </p> |
| |
| <p><i>[ |
| Alisdair: In addition to the (unsigned) long long problem, that whole paragraph |
| misses any reference to extended integral types supplied by the |
| implementation - one of the additions by core a couple of working papers |
| back. |
| ]</i></p> |
| |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.6.2.6.2 [ostream.inserters.arithmetic]/1 change the third sentence |
| </p> |
| |
| <blockquote> |
| When val is of type <tt>bool</tt>, <tt>long</tt>, <tt>unsigned |
| long</tt>, <ins>long long, unsigned long long,</ins> <tt>double</tt>, |
| <tt>long double</tt>, or <tt>const void*</tt>, the formatting conversion |
| occurs as if it performed the following code fragment: |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="643"></a>643. Impossible "as if" clauses</h3> |
| <p><b>Section:</b> 27.8.1.1 [filebuf], 22.2.2.2.2 [facet.num.put.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-02-20</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current standard 14882:2003(E) as well as N2134 have the |
| following |
| defects: |
| </p> |
| |
| <p> |
| 27.8.1.1 [filebuf]/5 says: |
| </p> |
| |
| <blockquote> |
| <p> |
| In order to support file I/O and multibyte/wide character conversion, conversions are performed using members of a |
| facet, referred to as <tt><i>a_codecvt</i></tt> in following sections, obtained "as if" by |
| </p> |
| <blockquote><pre>codecvt<charT,char,typename traits::state_type> <i>a_codecvt</i> = |
| use_facet<codecvt<charT,char,typename traits::state_type> >(getloc()); |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| <tt>use_facet</tt> returns a <tt>const facet</tt> reference and no facet is |
| copyconstructible, so the codecvt construction should fail to compile. |
| </p> |
| |
| <p> |
| A similar issue arises in 22.2.2.2.2 [facet.num.put.virtuals]/15 for <tt>num_punct</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 27.8.1.1 [filebuf]/5 change the "as if" code |
| </p> |
| |
| <blockquote><pre><ins>const </ins>codecvt<charT,char,typename traits::state_type><ins>&</ins> <i>a_codecvt</i> = |
| use_facet<codecvt<charT,char,typename traits::state_type> >(getloc()); |
| </pre></blockquote> |
| |
| <p> |
| In 22.2.2.2.2 [facet.num.put.virtuals]/15 (This is para 5 in N2134) change |
| </p> |
| |
| <blockquote> |
| <p> |
| A local variable <tt><i>punct</i></tt> is initialized via |
| </p> |
| <blockquote><pre><ins>const </ins>numpunct<charT><ins>&</ins> <i>punct</i> = use_facet< numpunct<charT> >(<i>str</i>.getloc() )<ins>;</ins> |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| (Please note also the additional provided trailing semicolon) |
| </p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="646"></a>646. const incorrect match_result members</h3> |
| <p><b>Section:</b> 28.10.4 [re.results.form] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-02-26</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 28.10.4 [re.results.form] (root and para 3) in N2134 defines the two function template |
| members format as non-const functions, although they are declared |
| as const in 28.10 [re.results]/3. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the missing <tt>const</tt> specifier to both <tt>format</tt> overloads described |
| in section 28.10.4 [re.results.form]. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="650"></a>650. regex_token_iterator and const correctness</h3> |
| <p><b>Section:</b> 28.12.2 [re.tokiter] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-03-05</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#re.tokiter">issues</a> in [re.tokiter].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Both the class definition of regex_token_iterator (28.12.2 |
| [re.tokiter]/6) and the latter member specifications (28.12.2.2 |
| [re.tokiter.comp]/1+2) declare both comparison operators as |
| non-const functions. Furtheron, both dereference operators are |
| unexpectedly also declared as non-const in 28.12.2 [re.tokiter]/6 |
| as well as in (28.12.2.3 [re.tokiter.deref]/1+2). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1) In (28.12.2 [re.tokiter]/6) change the current declarations |
| </p> |
| |
| <blockquote><pre>bool operator==(const regex_token_iterator&) <ins>const</ins>; |
| bool operator!=(const regex_token_iterator&) <ins>const</ins>; |
| const value_type& operator*() <ins>const</ins>; |
| const value_type* operator->() <ins>const</ins>; |
| </pre></blockquote> |
| |
| <p> |
| 2) In 28.12.2.2 [re.tokiter.comp] change the following declarations |
| </p> |
| |
| <blockquote><pre>bool operator==(const regex_token_iterator& right) <ins>const</ins>; |
| bool operator!=(const regex_token_iterator& right) <ins>const</ins>; |
| </pre></blockquote> |
| |
| <p> |
| 3) In 28.12.2.3 [re.tokiter.deref] change the following declarations |
| </p> |
| |
| <blockquote><pre>const value_type& operator*() <ins>const</ins>; |
| const value_type* operator->() <ins>const</ins>; |
| </pre></blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue (which |
| is to adopt the proposed wording in this issue). |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="651"></a>651. Missing preconditions for regex_token_iterator c'tors</h3> |
| <p><b>Section:</b> 28.12.2.1 [re.tokiter.cnstr] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-03-05</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#re.tokiter.cnstr">issues</a> in [re.tokiter.cnstr].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The text provided in 28.12.2.1 [re.tokiter.cnstr]/2+3 describes |
| the effects of the three non-default constructors of class |
| template regex_token_iterator but is does not clarify which values |
| are legal values for submatch/submatches. This becomes |
| an issue, if one takes 28.12.2 [re.tokiter]/9 into account, which explains |
| the notion of a "current match" by saying: |
| </p> |
| |
| <blockquote><p> |
| The <i>current match</i> is <tt>(*position).prefix()</tt> if <tt>subs[N] |
| == -1</tt>, or <tt>(*position)[subs[N]]</tt> for any other value of |
| <tt>subs[N]</tt>. |
| </p></blockquote> |
| |
| <p> |
| It's not clear to me, whether other negative values except -1 |
| are legal arguments or not - it seems they are not. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following precondition paragraph just before the current |
| 28.12.2.1 [re.tokiter.cnstr]/2: |
| </p> |
| |
| <blockquote><p> |
| <i>Requires:</i> Each of the initialization values of <tt>subs</tt> must be <tt>>= -1</tt>. |
| </p></blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue (which |
| is to adopt the proposed wording in this issue). |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="652"></a>652. regex_iterator and const correctness</h3> |
| <p><b>Section:</b> 28.12.1 [re.regiter] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-03-05</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Both the class definition of regex_iterator (28.12.1 [re.regiter]/1) |
| and the latter member specification (28.12.1.2 [re.regiter.comp]/1+2) |
| declare both comparison operators as |
| non-const functions. Furtheron, both dereference operators are |
| unexpectedly also declared as non-const in 28.12.1 [re.regiter]/1 |
| as well as in (28.12.1.3 [re.regiter.deref]/1+2). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| 1) In (28.12.1 [re.regiter]/1) change the current declarations |
| </p> |
| |
| <blockquote><pre>bool operator==(const regex_iterator&) <ins>const</ins>; |
| bool operator!=(const regex_iterator&) <ins>const</ins>; |
| const value_type& operator*() <ins>const</ins>; |
| const value_type* operator->() <ins>const</ins>; |
| </pre></blockquote> |
| |
| <p> |
| 2) In 28.12.1.3 [re.regiter.deref] change the following declarations |
| </p> |
| |
| <blockquote><pre>const value_type& operator*() <ins>const</ins>; |
| const value_type* operator->() <ins>const</ins>; |
| </pre></blockquote> |
| |
| <p> |
| 3) In 28.12.1.2 [re.regiter.comp] change the following declarations |
| </p> |
| |
| <blockquote><pre>bool operator==(const regex_iterator& right) <ins>const</ins>; |
| bool operator!=(const regex_iterator& right) <ins>const</ins>; |
| </pre></blockquote> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue (which |
| is to adopt the proposed wording in this issue). |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="654"></a>654. Missing IO roundtrip for random number engines</h3> |
| <p><b>Section:</b> 26.4.1.3 [rand.req.eng] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-03-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.req.eng">issues</a> in [rand.req.eng].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Table 98 and para 5 in 26.4.1.3 [rand.req.eng] specify |
| the IO insertion and extraction semantic of random |
| number engines. It can be shown, v.i., that the specification |
| of the extractor cannot guarantee to fulfill the requirement |
| from para 5: |
| </p> |
| |
| <blockquote><p> |
| If a textual representation written via os << x was |
| subsequently read via is >> v, then x == v provided that |
| there have been no intervening invocations of x or of v. |
| </p></blockquote> |
| |
| <p> |
| The problem is, that the extraction process described in |
| table 98 misses to specify that it will initially set the |
| if.fmtflags to ios_base::dec, see table 104: |
| </p> |
| |
| <blockquote><p> |
| dec: converts integer input or generates integer output |
| in decimal base |
| </p></blockquote> |
| |
| <p> |
| Proof: The following small program demonstrates the violation |
| of requirements (exception safety not fulfilled): |
| </p> |
| |
| <blockquote><pre>#include <cassert> |
| #include <ostream> |
| #include <iostream> |
| #include <iomanip> |
| #include <sstream> |
| |
| class RanNumEngine { |
| int state; |
| public: |
| RanNumEngine() : state(42) {} |
| |
| bool operator==(RanNumEngine other) const { |
| return state == other.state; |
| } |
| |
| template <typename Ch, typename Tr> |
| friend std::basic_ostream<Ch, Tr>& operator<<(std::basic_ostream<Ch, Tr>& os, RanNumEngine engine) { |
| Ch old = os.fill(os.widen(' ')); // Sets space character |
| std::ios_base::fmtflags f = os.flags(); |
| os << std::dec << std::left << engine.state; // Adds ios_base::dec|ios_base::left |
| os.fill(old); // Undo |
| os.flags(f); |
| return os; |
| } |
| |
| template <typename Ch, typename Tr> |
| friend std::basic_istream<Ch, Tr>& operator>>(std::basic_istream<Ch, Tr>& is, RanNumEngine& engine) { |
| // Uncomment only for the fix. |
| |
| //std::ios_base::fmtflags f = is.flags(); |
| //is >> std::dec; |
| is >> engine.state; |
| //is.flags(f); |
| return is; |
| } |
| }; |
| |
| int main() { |
| std::stringstream s; |
| s << std::setfill('#'); // No problem |
| s << std::oct; // Yikes! |
| // Here starts para 5 requirements: |
| RanNumEngine x; |
| s << x; |
| RanNumEngine v; |
| s >> v; |
| assert(x == v); // Fails: 42 == 34 |
| } |
| </pre></blockquote> |
| |
| <p> |
| A second, minor issue seems to be, that the insertion |
| description from table 98 unnecessarily requires the |
| addition of ios_base::fixed (which only influences floating-point |
| numbers). Its not entirely clear to me whether the proposed |
| standard does require that the state of random number engines |
| is stored in integral types or not, but I have the impression |
| that this is the indent, see e.g. p. 3 |
| </p> |
| |
| <blockquote><p> |
| The specification of each random number engine defines the |
| size of its state in multiples of the size of its result_type. |
| </p></blockquote> |
| |
| <p> |
| If other types than integrals are supported, then I wonder why |
| no requirements are specified for the precision of the stream. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="655"></a>655. Signature of generate_canonical not useful</h3> |
| <p><b>Section:</b> 26.4.7.2 [rand.util.canonical] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-03-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.canonical">issues</a> in [rand.util.canonical].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 26.4.2 [rand.synopsis] we have the declaration |
| </p> |
| |
| <blockquote><pre>template<class RealType, class UniformRandomNumberGenerator, |
| size_t bits> |
| result_type generate_canonical(UniformRandomNumberGenerator& g); |
| </pre></blockquote> |
| |
| <p> |
| Besides the "result_type" issue (already recognized by Bo Persson |
| at Sun, 11 Feb 2007 05:26:47 GMT in this group) it's clear, that |
| the template parameter order is not reasonably choosen: Obviously |
| one always needs to specify all three parameters, although usually |
| only two are required, namely the result type RealType and the |
| wanted bits, because UniformRandomNumberGenerator can usually |
| be deduced. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="660"></a>660. Missing Bitwise Operations</h3> |
| <p><b>Section:</b> 20.6 [function.objects] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2007-04-02</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#function.objects">issues</a> in [function.objects].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p>Section 20.6 [function.objects] provides <span id="st" name="st" class="st">function</span> |
| <span id="st" name="st" class="st">objects</span> for some unary and binary |
| operations, but others are missing. In a LWG reflector discussion, beginning |
| with c++std-lib-18078, pros and cons of adding some of the missing operations |
| were discussed. Bjarne Stroustrup commented "Why standardize what isn't used? |
| Yes, I see the chicken and egg problems here, but it would be nice to see a |
| couple of genuine uses before making additions."</p> |
| <p>A number of libraries, including Rogue Wave, GNU, Adobe ASL, and Boost, have |
| already added these functions, either publicly or for internal use. For example, |
| Doug Gregor commented: "Boost will also add ... (|, &, ^) in 1.35.0, because we |
| need those <span id="st" name="st" class="st">function</span> |
| <span id="st" name="st" class="st">objects</span> to represent various parallel |
| collective operations (reductions, prefix reductions, etc.) in the new Message |
| Passing Interface (MPI) library."</p> |
| <p>Because the bitwise operators have the strongest use cases, the proposed |
| resolution is limited to them.</p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p>To 20.6 [function.objects], Function objects, paragraph 2, add to the header |
| <functional> synopsis:</p> |
| <blockquote> |
| <pre>template <class T> struct bit_and; |
| template <class T> struct bit_or; |
| template <class T> struct bit_xor;</pre> |
| </blockquote> |
| <p>At a location in clause 20 to be determined by the Project Editor, add:</p> |
| <blockquote> |
| <p>The library provides basic function object classes for all of the bitwise |
| operators in the language ([expr.bit.and], [expr.or], [exp.xor]).</p> |
| <pre>template <class T> struct bit_and : binary_function<T,T,T> { |
| T operator()(const T& x , const T& y ) const; |
| };</pre> |
| <blockquote> |
| <p><code>operator()</code> returns<code> x & y</code> .</p> |
| </blockquote> |
| <pre>template <class T> struct bit_or : binary_function<T,T,T> { |
| T operator()(const T& x , const T& y ) const; |
| };</pre> |
| <blockquote> |
| <p><code>operator()</code> returns <code>x | y</code> .</p> |
| </blockquote> |
| <pre>template <class T> struct bit_xor : binary_function<T,T,T> { |
| T operator()(const T& x , const T& y ) const; |
| };</pre> |
| <blockquote> |
| <p><code>operator()</code> returns <code>x ^ y</code> .</p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="661"></a>661. New 27.6.1.2.2 changes make special extractions useless</h3> |
| <p><b>Section:</b> 27.6.1.2.2 [istream.formatted.arithmetic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-04-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#istream.formatted.arithmetic">issues</a> in [istream.formatted.arithmetic].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| To the more drastic changes of 27.6.1.2.2 [istream.formatted.arithmetic] in the current draft N2134 belong |
| the explicit description of the extraction of the types short and int in |
| terms of as-if code fragments. |
| </p> |
| |
| <ol> |
| <li> |
| The corresponding as-if extractions in paragraph 2 and 3 will never |
| result in a change of the operator>> argument val, because the |
| contents of the local variable lval is in no case written into val. |
| Furtheron both fragments need a currently missing parentheses in the |
| beginning of the if-statement to be valid C++. |
| </li> |
| <li>I would like to ask whether the omission of a similar explicit |
| extraction of unsigned short and unsigned int in terms of long - |
| compared to their corresponding new insertions, as described in |
| 27.6.2.6.2 [ostream.inserters.arithmetic], is a deliberate decision or |
| an |
| oversight. |
| </li> |
| </ol> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <ol> |
| <li> |
| <p> |
| In 27.6.1.2.2 [istream.formatted.arithmetic]/2 change the current as-if code fragment |
| </p> |
| <blockquote><pre>typedef num_get<charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet<numget>(loc).get(*this, 0, *this, err, lval ); |
| if (err == 0) <ins>{</ins> |
| <del>&&</del> <ins>if</ins> (lval < numeric_limits<short>::min() || numeric_limits<short>::max() < lval)<del>)</del> |
| err = ios_base::failbit; |
| <ins>else |
| val = static_cast<short>(lval); |
| }</ins> |
| setstate(err); |
| </pre></blockquote> |
| |
| <p> |
| Similarily in 27.6.1.2.2 [istream.formatted.arithmetic]/3 change the current as-if fragment |
| </p> |
| |
| <blockquote><pre>typedef num_get<charT,istreambuf_iterator<charT,traits> > numget; |
| iostate err = 0; |
| long lval; |
| use_facet<numget>(loc).get(*this, 0, *this, err, lval ); |
| if (err == 0) <ins>{</ins> |
| <del>&&</del> <ins>if</ins> (lval < numeric_limits<int>::min() || numeric_limits<int>::max() < lval)<del>)</del> |
| err = ios_base::failbit; |
| <ins>else |
| val = static_cast<int>(lval); |
| }</ins> |
| setstate(err); |
| </pre></blockquote> |
| </li> |
| <li> |
| --- |
| </li> |
| </ol> |
| |
| |
| <p><i>[ |
| Kona (2007): Note to the editor: the name lval in the call to <tt>use_facet</tt> |
| is incorrectly italicized in the code fragments corresponding to |
| <tt>operator>>(short &)</tt> and <tt>operator >>(int &)</tt>. Also, val -- which appears |
| twice on the line with the <tt>static_cast</tt> in the proposed resolution -- |
| should be italicized. Also, in response to part two of the issue: this |
| is deliberate. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="664"></a>664. <tt>do_unshift</tt> for <tt>codecvt<char, char, mbstate_t></tt></h3> |
| <p><b>Section:</b> 22.2.1.4.2 [locale.codecvt.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thomas Plum <b>Date:</b> 2007-04-16</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt.virtuals">issues</a> in [locale.codecvt.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 22.2.1.4.2 [locale.codecvt.virtuals], para 7 says (regarding <tt>do_unshift</tt>): |
| </p> |
| |
| <blockquote><p> |
| <i>Effects:</i> Places characters starting at to that should be appended to |
| terminate a sequence when the current <tt>stateT</tt> is given by |
| <tt><i>state</i></tt>.<sup>237)</sup> Stores no more than <tt>(<i>to_limit</i> - |
| <i>to</i>)</tt> destination elements, and leaves the <tt><i>to_next</i></tt> |
| pointer pointing one beyond the last element successfully stored. |
| <em><tt>codecvt<char, char, mbstate_t></tt> stores no characters.</em> |
| </p></blockquote> |
| |
| <p> |
| The following objection has been raised: |
| </p> |
| |
| <blockquote><p> |
| Since the C++ Standard permits a nontrivial conversion for the required |
| instantiations of <tt>codecvt</tt>, it is overly restrictive to say that |
| <tt>do_unshift</tt> must store no characters and return <tt>noconv</tt>. |
| </p></blockquote> |
| |
| <p> |
| [Plum ref _222152Y50] |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 22.2.1.4.2 [locale.codecvt.virtuals], p7: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Effects:</i> Places characters starting at <i>to</i> that should be |
| appended to terminate a sequence when the current <tt>stateT</tt> is |
| given by state.<sup>237)</sup> Stores no more than (<i>to_limit -to</i>) |
| destination elements, and leaves the <i>to_next</i> pointer pointing one |
| beyond the last element successfully stored. <del><tt>codecvt<char, char, |
| mbstate_t></tt> stores no characters.</del> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="665"></a>665. <tt>do_unshift</tt> return value</h3> |
| <p><b>Section:</b> 22.2.1.4.2 [locale.codecvt.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thomas Plum <b>Date:</b> 2007-04-16</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.codecvt.virtuals">issues</a> in [locale.codecvt.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 22.2.1.4.2 [locale.codecvt.virtuals], para 8 says: |
| </p> |
| |
| <blockquote><p> |
| <tt>codecvt<char,char,mbstate_t></tt>, returns <tt>noconv</tt>. |
| </p></blockquote> |
| |
| <p> |
| The following objection has been raised: |
| </p> |
| |
| <blockquote><p> |
| Despite what the C++ Standard |
| says, <tt>unshift</tt> can't always return <tt>noconv</tt> for the default facets, since |
| they can be nontrivial. At least one implementation does whatever the |
| C functions do. |
| </p></blockquote> |
| |
| <p> |
| [Plum ref _222152Y62] |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 22.2.1.4.2 [locale.codecvt.virtuals], p8: |
| </p> |
| |
| <blockquote> |
| <p><i>Returns:</i> An enumeration value, as summarized in Table 76:</p> |
| <p>...</p> |
| <p> |
| <del><tt>codecvt<char,char,mbstate_t></tt>, returns <tt>noconv</tt>.</del> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="666"></a>666. <tt>moneypunct::do_curr_symbol()</tt></h3> |
| <p><b>Section:</b> 22.2.6.3.2 [locale.moneypunct.virtuals] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thomas Plum <b>Date:</b> 2007-04-16</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#locale.moneypunct.virtuals">issues</a> in [locale.moneypunct.virtuals].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 22.2.6.3.2 [locale.moneypunct.virtuals], para 4 footnote 257 says |
| </p> |
| |
| <blockquote><p> |
| <sup>257)</sup> For international |
| specializations (second template parameter <tt>true</tt>) this is always four |
| characters long, usually three letters and a space. |
| </p></blockquote> |
| |
| <p> |
| The following objection has been raised: |
| </p> |
| |
| <blockquote><p> |
| The international currency |
| symbol is whatever the underlying locale says it is, not necessarily |
| four characters long. |
| </p></blockquote> |
| |
| <p> |
| [Plum ref _222632Y41] |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change footnote 253 in 22.2.6.3.2 [locale.moneypunct.virtuals]: |
| </p> |
| |
| <blockquote> |
| <p> |
| <sup>253)</sup> For international specializations (second template |
| parameter <tt>true</tt>) this is <del>always</del> <ins>typically</ins> |
| four characters long, usually three letters and a space. |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="672"></a>672. Swappable requirements need updating</h3> |
| <p><b>Section:</b> 20.1.1 [utility.arg.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-05-04</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#utility.arg.requirements">active issues</a> in [utility.arg.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#utility.arg.requirements">issues</a> in [utility.arg.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current <tt>Swappable</tt> is: |
| </p> |
| |
| <blockquote> |
| <table border="1"> |
| <caption>Table 37: <tt>Swappable</tt> requirements <b>[swappable]</b></caption> |
| <tbody><tr><th>expression</th><th>return type</th><th>post-condition</th></tr> |
| <tr><td><tt>swap(s,t)</tt></td><td><tt>void</tt></td><td><tt>t</tt> has the value originally held by <tt>u</tt>, and <tt>u</tt> has the value originally |
| held by <tt>t</tt></td></tr> |
| <tr><td colspan="3"> |
| <p> |
| The Swappable requirement is met by satisfying one or more of the following conditions: |
| </p> |
| <ul> |
| <li> |
| <tt>T</tt> is Swappable if <tt>T</tt> satisfies the <tt>CopyConstructible</tt> requirements (Table 34) |
| and the <tt>CopyAssignable</tt> requirements (Table 36); |
| </li> |
| <li> |
| <tt>T</tt> is Swappable if a namespace scope function named <tt>swap</tt> exists in the same |
| namespace as the definition of <tt>T</tt>, such that the expression <tt>swap(t,u)</tt> is valid |
| and has the semantics described in this table. |
| </li> |
| </ul> |
| </td></tr> |
| </tbody></table> |
| </blockquote> |
| |
| <p> |
| With the passage of rvalue reference into the language, <tt>Swappable</tt> needs to be updated to |
| require only <tt>MoveConstructible</tt> and <tt>MoveAssignable</tt>. This is a minimum. |
| </p> |
| |
| <p> |
| Additionally we may want to support proxy references such that the following code is acceptable: |
| </p> |
| |
| <blockquote><pre>namespace Mine { |
| |
| template <class T> |
| struct proxy {...}; |
| |
| template <class T> |
| struct proxied_iterator |
| { |
| typedef T value_type; |
| typedef proxy<T> reference; |
| reference operator*() const; |
| ... |
| }; |
| |
| struct A |
| { |
| // heavy type, has an optimized swap, maybe isn't even copyable or movable, just swappable |
| void swap(A&); |
| ... |
| }; |
| |
| void swap(A&, A&); |
| void swap(proxy<A>, A&); |
| void swap(A&, proxy<A>); |
| void swap(proxy<A>, proxy<A>); |
| |
| } // Mine |
| |
| ... |
| |
| Mine::proxied_iterator<Mine::A> i(...) |
| Mine::A a; |
| swap(*i1, a); |
| </pre></blockquote> |
| |
| <p> |
| I.e. here is a call to <tt>swap</tt> which the user enables swapping between a proxy to a class and the class |
| itself. We do not need to anything in terms of implementation except not block their way with overly |
| constrained concepts. That is, the <tt>Swappable</tt> concept should be expanded to allow swapping |
| between two different types for the case that one is binding to a user-defined <tt>swap</tt>. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change 20.1.1 [utility.arg.requirements]: |
| </p> |
| |
| <blockquote> |
| |
| <p> |
| -1- The template definitions in the C++ Standard Library refer to various |
| named requirements whose details are set out in tables 31-38. In these |
| tables, <tt>T</tt> is a type to be supplied by a C++ program |
| instantiating a template; <tt>a</tt>, <tt>b</tt>, and <tt>c</tt> are |
| values of type <tt>const T</tt>; <tt>s</tt> and <tt>t</tt> are modifiable |
| lvalues of type <tt>T</tt>; <tt>u</tt> is a value of type (possibly |
| <tt>const</tt>) <tt>T</tt>; and <tt>rv</tt> is a non-<tt>const</tt> |
| rvalue of type <tt>T</tt>. |
| </p> |
| |
| <table border="1"> |
| <caption>Table 37: <tt>Swappable</tt> requirements <b>[swappable]</b></caption> |
| <tbody><tr><th>expression</th><th>return type</th><th>post-condition</th></tr> |
| <tr><td><tt>swap(s,t)</tt></td><td><tt>void</tt></td> |
| <td><tt>t</tt> has the value originally |
| held by <tt>u</tt>, and |
| <tt>u</tt> has the value originally held |
| by <tt>t</tt></td></tr> |
| <tr><td colspan="3"> |
| <p> |
| The <tt>Swappable</tt> requirement is met by satisfying one or more of the following conditions: |
| </p> |
| <ul> |
| <li> |
| <tt>T</tt> is <tt>Swappable</tt> if <tt>T</tt> satisfies the |
| <del><tt>CopyConstructible</tt></del> <ins>MoveConstructible</ins> |
| requirements (Table <del>34</del> <ins>33</ins>) and the <del><tt>CopyAssignable</tt></del> <ins>MoveAssignable</ins> |
| requirements (Table <del>36</del> <ins>35</ins>); |
| </li> |
| <li> |
| <tt>T</tt> is <tt>Swappable</tt> if a namespace scope function named |
| <tt>swap</tt> exists in the same namespace as the definition of |
| <tt>T</tt>, such that the expression |
| <tt>swap(t,u)</tt> is valid and has the |
| semantics described in this table. |
| </li> |
| </ul> |
| </td></tr> |
| </tbody></table> |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): We like the change to the <tt>Swappable</tt> requirements to use |
| move semantics. The issue relating to the support of proxies is |
| separable from the one relating to move semantics, and it's bigger than |
| just swap. We'd like to address only the move semantics changes under |
| this issue, and open a separated issue (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#742">742</a>) to handle proxies. Also, there |
| may be a third issue, in that the current definition of <tt>Swappable</tt> does |
| not permit rvalues to be operands to a swap operation, and Howard's |
| proposed resolution would allow the right-most operand to be an rvalue, |
| but it would not allow the left-most operand to be an rvalue (some swap |
| functions in the library have been overloaded to permit left operands to |
| swap to be rvalues). |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="673"></a>673. <tt>unique_ptr</tt> update</h3> |
| <p><b>Section:</b> 20.7.11 [unique.ptr] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-05-04</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#unique.ptr">issues</a> in [unique.ptr].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Since the publication of |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">N1856</a> |
| there have been a few small but significant advances which should be included into |
| <tt>unique_ptr</tt>. There exists a |
| <a href="http://home.twcny.rr.com/hinnant/cpp_extensions/unique_ptr.html">example implmenation</a> |
| for all of these changes. |
| </p> |
| |
| <ul> |
| |
| <li> |
| <p> |
| Even though <tt>unique_ptr<void></tt> is not a valid use case (unlike for <tt>shared_ptr<void></tt>), |
| unexpected cases to crop up which require the instantiation of the interface of <tt>unique_ptr<void></tt> |
| even if it is never used. For example see |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#541">LWG 541</a> for how this accidently |
| happened to <tt>auto_ptr</tt>. I believe the most robust way to protect <tt>unique_ptr</tt> against this |
| type of failure is to augment the return type of <tt>unique_ptr<T>:operator*()</tt> with |
| <tt>add_lvalue_reference<T>::type</tt>. This means that given an instantiated <tt>unique_ptr<void></tt> |
| the act of dereferencing it will simply return <tt>void</tt> instead of causing a compile time failure. |
| This is simpler than creating a <tt>unique_ptr<void></tt> specialization which isn't robust in the |
| face of <tt><i>cv-</i></tt>qualified <tt>void</tt> types. |
| </p> |
| |
| <p> |
| This resolution also supports instantiations such as <tt>unique_ptr<void, free_deleter></tt> |
| which could be very useful to the client. |
| </p> |
| |
| </li> |
| |
| <li> |
| <p> |
| Efforts have been made to better support containers and smart pointers in shared |
| memory contexts. One of the key hurdles in such support is not assuming that a |
| pointer type is actually a <tt>T*</tt>. This can easily be accomplished |
| for <tt>unique_ptr</tt> by having the deleter define the pointer type: |
| <tt>D::pointer</tt>. Furthermore this type can easily be defaulted to |
| <tt>T*</tt> should the deleter <tt>D</tt> choose not to define a pointer |
| type (example implementation |
| <a href="http://home.twcny.rr.com/hinnant/cpp_extensions/unique_ptr.html">here</a>). |
| This change has no run time overhead. It has no interface overhead on |
| authors of custom delter types. It simply allows (but not requires) |
| authors of custom deleter types to define a smart pointer for the |
| storage type of <tt>unique_ptr</tt> if they find such functionality |
| useful. <tt>std::default_delete</tt> is an example of a deleter which |
| defaults <tt>pointer</tt> to <tt>T*</tt> by simply ignoring this issue |
| and not including a <tt>pointer typedef</tt>. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| When the deleter type is a function pointer then it is unsafe to construct |
| a <tt>unique_ptr</tt> without specifying the function pointer in the constructor. |
| This case is easy to check for with a <tt>static_assert</tt> assuring that the |
| deleter is not a pointer type in those constructors which do not accept deleters. |
| </p> |
| |
| <blockquote><pre>unique_ptr<A, void(*)(void*)> p(new A); // error, no function given to delete the pointer! |
| </pre></blockquote> |
| |
| </li> |
| |
| </ul> |
| |
| <p><i>[ |
| Kona (2007): We don't like the solution given to the first bullet in |
| light of concepts. The second bullet solves the problem of supporting |
| fancy pointers for one library component only. The full LWG needs to |
| decide whether to solve the problem of supporting fancy pointers |
| piecemeal, or whether a paper addressing the whole library is needed. We |
| think that the third bullet is correct. |
| ]</i></p> |
| |
| |
| <p><i>[ |
| Post Kona: Howard adds example user code related to the first bullet: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <pre>void legacy_code(void*, std::size_t); |
| |
| void foo(std::size_t N) |
| { |
| std::unique_ptr<void, void(*)(void*)> ptr(std::malloc(N), std::free); |
| legacy_code(ptr.get(), N); |
| } // unique_ptr used for exception safety purposes |
| </pre> |
| </blockquote> |
| |
| <p> |
| I.e. <tt>unique_ptr<void></tt> <i>is</i> a useful tool that we don't want |
| to disable with concepts. The only part of <tt>unique_ptr<void></tt> we |
| want to disable (with concepts or by other means) are the two member functions: |
| </p> |
| |
| <blockquote><pre>T& operator*() const; |
| T* operator->() const; |
| </pre></blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p><i>[ |
| I am grateful for the generous aid of Peter Dimov and Ion Gaztañaga in helping formulate and review |
| the proposed resolutions below. |
| ]</i></p> |
| |
| |
| <ul> |
| <li> |
| |
| <p> |
| Change 20.7.11.2 [unique.ptr.single]: |
| </p> |
| |
| <blockquote><pre>template <class T, class D = default_delete<T>> class unique_ptr { |
| ... |
| <del>T&</del> <ins>typename add_lvalue_reference<T>::type</ins> operator*() const; |
| ... |
| }; |
| </pre></blockquote> |
| |
| <p> |
| Change 20.7.11.2.4 [unique.ptr.single.observers]: |
| </p> |
| |
| <blockquote><pre><del>T&</del> <ins>typename add_lvalue_reference<T>::type</ins> operator*() const; |
| </pre></blockquote> |
| |
| </li> |
| |
| <li> |
| <p> |
| Change 20.7.11.2 [unique.ptr.single]: |
| </p> |
| |
| <blockquote><pre>template <class T, class D = default_delete<T>> class unique_ptr { |
| public: |
| <ins>typedef <i>implementation (see description below)</i> pointer;</ins> |
| ... |
| explicit unique_ptr(<del>T*</del> <ins>pointer</ins> p); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined (see description below)</i> d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined (see description below)</i> d); |
| ... |
| <del>T*</del> <ins>pointer</ins> operator->() const; |
| <del>T*</del> <ins>pointer</ins> get() const; |
| ... |
| <del>T*</del> <ins>pointer</ins> release(); |
| void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>); |
| }; |
| </pre></blockquote> |
| |
| <p> |
| <ins> |
| -3- If the type <tt>remove_reference<D>::type::pointer</tt> |
| exists, then <tt>unique_ptr<T, D>::pointer</tt> is a typedef to |
| <tt>remove_reference<D>::type::pointer</tt>. Otherwise |
| <tt>unique_ptr<T, D>::pointer</tt> is a typedef to <tt>T*</tt>. |
| The type <tt>unique_ptr<T, D>::pointer</tt> shall be <tt>CopyConstructible</tt> |
| and <tt>CopyAssignable</tt>. |
| </ins> |
| </p> |
| |
| <p> |
| Change 20.7.11.2.1 [unique.ptr.single.ctor]: |
| </p> |
| |
| <blockquote><pre>unique_ptr(<del>T*</del> <ins>pointer</ins> p); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A& d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, A&& d); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, A& d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, A&& d); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A& d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, const A&& d); |
| ... |
| </pre></blockquote> |
| |
| <p> |
| -23- <i>Requires:</i> If <tt>D</tt> is not a reference type, |
| construction of the deleter <tt>D</tt> from an rvalue of type <tt>E</tt> |
| <del>must</del> <ins>shall</ins> be well formed and not throw an exception. If <tt>D</tt> is a |
| reference type, then <tt>E</tt> <del>must</del> <ins>shall</ins> be the same type as <tt>D</tt> |
| (diagnostic required). <del><tt>U*</tt></del> <ins><tt>unique_ptr<U,E>::pointer</tt></ins> |
| <del>must</del> <ins>shall</ins> be implicitly convertible to <del><tt>T*</tt></del> |
| <ins>pointer</ins>. |
| </p> |
| |
| <p> |
| -25- <i>Postconditions:</i> <tt>get() == value u.get()</tt> had before |
| the construction, modulo any required offset adjustments resulting from |
| the cast from <del><tt>U*</tt></del> |
| <ins><tt>unique_ptr<U,E>::pointer</tt></ins> to <del><tt>T*</tt></del> |
| <ins>pointer</ins>. <tt>get_deleter()</tt> returns a reference to the |
| internally stored deleter which was constructed from |
| <tt>u.get_deleter()</tt>. |
| </p> |
| |
| <p> |
| Change 20.7.11.2.3 [unique.ptr.single.asgn]: |
| </p> |
| |
| <blockquote> |
| <p> |
| -8- <i>Requires:</i> Assignment of the deleter <tt>D</tt> from an rvalue |
| <tt>D</tt> <del>must</del> <ins>shall</ins> not throw an exception. <del><tt>U*</tt></del> |
| <ins><tt>unique_ptr<U,E>::pointer</tt></ins> <del>must</del> <ins>shall</ins> be implicitly |
| convertible to <del><tt>T*</tt></del> <ins>pointer</ins>. |
| </p> |
| </blockquote> |
| |
| <p> |
| Change 20.7.11.2.4 [unique.ptr.single.observers]: |
| </p> |
| |
| <blockquote> |
| <pre><del>T*</del> <ins>pointer</ins> operator->() const;</pre> |
| ... |
| <pre><del>T*</del> <ins>pointer</ins> get() const;</pre> |
| </blockquote> |
| |
| <p> |
| Change 20.7.11.2.5 [unique.ptr.single.modifiers]: |
| </p> |
| |
| <blockquote> |
| <pre><del>T*</del> <ins>pointer</ins> release();</pre> |
| ... |
| <pre>void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>);</pre> |
| </blockquote> |
| |
| <p> |
| Change 20.7.11.3 [unique.ptr.runtime]: |
| </p> |
| |
| <blockquote><pre>template <class T, class D> class unique_ptr<T[], D> { |
| public: |
| <ins>typedef <i>implementation</i> pointer;</ins> |
| ... |
| explicit unique_ptr(<del>T*</del> <ins>pointer</ins> p); |
| ... |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| ... |
| <del>T*</del> <ins>pointer</ins> get() const; |
| ... |
| <del>T*</del> <ins>pointer</ins> release(); |
| void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>); |
| }; |
| </pre></blockquote> |
| |
| <p> |
| Change 20.7.11.3.1 [unique.ptr.runtime.ctor]: |
| </p> |
| |
| <blockquote> |
| <pre>unique_ptr(<del>T*</del> <ins>pointer</ins> p); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| unique_ptr(<del>T*</del> <ins>pointer</ins> p, <i>implementation defined</i> d); |
| </pre> |
| |
| <p> |
| These constructors behave the same as in the primary template except |
| that they do not accept pointer types which are convertible to |
| <del><tt>T*</tt></del> <ins><tt>pointer</tt></ins>. [<i>Note:</i> One |
| implementation technique is to create private templated overloads of |
| these members. <i>-- end note</i>] |
| </p> |
| </blockquote> |
| |
| <p> |
| Change 20.7.11.3.3 [unique.ptr.runtime.modifiers]: |
| </p> |
| |
| <blockquote> |
| <pre>void reset(<del>T*</del> <ins>pointer</ins> p = <del>0</del> <ins>pointer()</ins>); |
| </pre> |
| |
| <p> |
| -1- <i>Requires:</i> Does not accept pointer types which are convertible |
| to <del><tt>T*</tt></del> <ins><tt>pointer</tt></ins> (diagnostic |
| required). [<i>Note:</i> One implementation technique is to create a private |
| templated overload. <i>-- end note</i>] |
| </p> |
| </blockquote> |
| |
| </li> |
| |
| <li> |
| |
| <p> |
| Change 20.7.11.2.1 [unique.ptr.single.ctor]: |
| </p> |
| |
| <blockquote> |
| <pre>unique_ptr();</pre> |
| <blockquote> |
| <p> |
| <i>Requires:</i> <tt>D</tt> <del>must</del> <ins>shall</ins> be default constructible, and that |
| construction <del>must</del> <ins>shall</ins> not throw an exception. <tt>D</tt> <del>must</del> <ins>shall</ins> not be a |
| reference type <ins>or pointer type (diagnostic required)</ins>. |
| </p> |
| </blockquote> |
| <pre>unique_ptr(<del>T*</del> <ins>pointer</ins> p);</pre> |
| <blockquote> |
| <p> |
| <i>Requires:</i> The expression <tt>D()(p)</tt> <del>must</del> <ins>shall</ins> be well formed. |
| The default constructor of <tt>D</tt> <del>must</del> <ins>shall</ins> not throw an exception. |
| <tt>D</tt> <del>must</del> <ins>shall</ins> not be a reference type <ins>or pointer type (diagnostic |
| required)</ins>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| </li> |
| |
| </ul> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="674"></a>674. <tt>shared_ptr</tt> interface changes for consistency with N1856</h3> |
| <p><b>Section:</b> 20.7.12.2 [util.smartptr.shared] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2007-05-05</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#util.smartptr.shared">active issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared">issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">N1856</a> does not propose |
| any changes to <tt>shared_ptr</tt>. It needs to be updated to use a rvalue reference where appropriate |
| and to interoperate with <tt>unique_ptr</tt> as it does with <tt>auto_ptr</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| |
| <p> |
| Change 20.7.12.2 [util.smartptr.shared] as follows: |
| </p> |
| |
| <blockquote> |
| <pre>template<class Y> explicit shared_ptr(auto_ptr<Y><del>&</del><ins>&&</ins> r); |
| <ins>template<class Y, class D> explicit shared_ptr(const unique_ptr<Y,D>& r) = delete; |
| template<class Y, class D> explicit shared_ptr(unique_ptr<Y,D>&& r);</ins> |
| ... |
| template<class Y> shared_ptr& operator=(auto_ptr<Y><del>&</del><ins>&&</ins> r); |
| <ins>template<class Y, class D> shared_ptr& operator=(const unique_ptr<Y,D>& r) = delete; |
| template<class Y, class D> shared_ptr& operator=(unique_ptr<Y,D>&& r);</ins></pre> |
| </blockquote> |
| |
| <p> |
| Change 20.7.12.2.1 [util.smartptr.shared.const] as follows: |
| </p> |
| |
| <blockquote> |
| <pre><ins>template<class Y> shared_ptr(auto_ptr<Y><del>&</del><ins>&&</ins> r);</ins></pre> |
| </blockquote> |
| |
| <p> |
| Add to 20.7.12.2.1 [util.smartptr.shared.const]: |
| </p> |
| |
| <blockquote> |
| <pre><ins>template<class Y, class D> shared_ptr(unique_ptr<Y, D>&& r);</ins></pre> |
| <blockquote> |
| |
| <p><ins> |
| <i>Effects:</i> Equivalent to <tt>shared_ptr( r.release(), r.get_deleter() )</tt> when <tt>D</tt> is |
| not a reference type, <tt>shared_ptr( r.release(), ref( r.get_deleter() ) )</tt> |
| otherwise. |
| </ins></p> |
| |
| <p><ins> |
| <i>Exception safety:</i> If an exception is thrown, the constructor has no effect. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| <p> |
| Change 20.7.12.2.3 [util.smartptr.shared.assign] as follows: |
| </p> |
| |
| <blockquote> |
| <pre>template<class Y> shared_ptr& operator=(auto_ptr<Y><del>&</del><ins>&&</ins> r);</pre> |
| </blockquote> |
| |
| <p> |
| Add to 20.7.12.2.3 [util.smartptr.shared.assign]: |
| </p> |
| |
| <blockquote> |
| <pre><ins>template<class Y, class D> shared_ptr& operator=(unique_ptr<Y,D>&& r);</ins></pre> |
| |
| <blockquote> |
| <p><ins> |
| -4- <i>Effects:</i> Equivalent to <tt>shared_ptr(std::move(r)).swap(*this)</tt>. |
| </ins></p> |
| <p><ins> |
| -5- <i>Returns:</i> <tt>*this</tt>. |
| </ins></p> |
| </blockquote> |
| |
| </blockquote> |
| |
| |
| |
| <p><i>[ |
| Kona (2007): We may need to open an issue (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#743">743</a>) to deal with the question of |
| whether <tt>shared_ptr</tt> needs an rvalue <tt>swap</tt>. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="677"></a>677. Weaknesses in seed_seq::randomize [rand.util.seedseq]</h3> |
| <p><b>Section:</b> 26.4.7.1 [rand.util.seedseq] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Charles Karney <b>Date:</b> 2007-05-15</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>seed_seq::randomize</tt> provides a mechanism for initializing random number |
| engines which ideally would yield "distant" states when given "close" |
| seeds. The algorithm for <tt>seed_seq::randomize</tt> given in the current |
| Working Draft for C++, |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2284.pdf">N2284</a> |
| (2007-05-08), has 3 weaknesses |
| </p> |
| |
| <ol> |
| <li> |
| <p> Collisions in state. Because of the way the state is initialized, |
| seeds of different lengths may result in the same state. The |
| current version of seed_seq has the following properties:</p> |
| <ul> |
| <li> For a given <tt>s <= n</tt>, each of the 2^(32s) seed vectors results in a |
| distinct state.</li> |
| </ul> |
| <p> |
| The proposed algorithm (below) has the considerably stronger |
| properties:</p> |
| <ul> |
| <li> All of the <tt>(2^(32n)-1)/(2^32-1)</tt> seed vectors of lengths <tt>s < n</tt> |
| result in distinct states. |
| </li> |
| <li> All of the <tt>2^(32n)</tt> seed vectors of length <tt>s == n</tt> result in |
| distinct states. |
| </li> |
| </ul> |
| </li> |
| <li> |
| <p> Poor mixing of <tt>v'</tt>s entropy into the state. Consider <tt>v.size() == n</tt> |
| and hold <tt>v[n/2]</tt> thru <tt>v[n-1]</tt> fixed while varying <tt>v[0]</tt> thru <tt>v[n/2-1]</tt>, |
| a total of <tt>2^(16n)</tt> possibilities. Because of the simple recursion |
| used in <tt>seed_seq</tt>, <tt>begin[n/2]</tt> thru <tt>begin[n-1]</tt> can take on only 2^64 |
| possible states.</p> |
| |
| <p> The proposed algorithm uses a more complex recursion which results |
| in much better mixing.</p> |
| </li> |
| <li> <tt>seed_seq::randomize</tt> is undefined for <tt>v.size() == 0</tt>. The proposed |
| algorithm remedies this. |
| </li> |
| </ol> |
| <p> |
| The current algorithm for <tt>seed_seq::randomize</tt> is adapted by me from the |
| initialization procedure for the Mersenne Twister by Makoto Matsumoto |
| and Takuji Nishimura. The weakness (2) given above was communicated to |
| me by Matsumoto last year. |
| </p> |
| <p> |
| The proposed replacement for <tt>seed_seq::randomize</tt> is due to Mutsuo Saito, |
| a student of Matsumoto, and is given in the implementation of the |
| SIMD-oriented Fast Mersenne Twister random number generator SFMT. |
| <a href="http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/SFMT/index.html">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/index.html</a> |
| <a href="http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/SFMT/SFMT-src-1.2.tar.gz">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/SFMT-src-1.2.tar.gz</a> |
| </p> |
| <p> |
| See |
| Mutsuo Saito, |
| An Application of Finite Field: Design and Implementation of 128-bit |
| Instruction-Based Fast Pseudorandom Number Generator, |
| Master's Thesis, Dept. of Math., Hiroshima University (Feb. 2007) |
| <a href="http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/SFMT/M062821.pdf">http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/SFMT/M062821.pdf</a> |
| </p> |
| <p> |
| One change has been made here, namely to treat the case of small <tt>n</tt> |
| (setting <tt>t = (n-1)/2</tt> for <tt>n < 7</tt>). |
| </p> |
| <p> |
| Since <tt>seed_seq</tt> was introduced relatively recently there is little cost |
| in making this incompatible improvement to it. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="678"></a>678. Changes for [rand.req.eng]</h3> |
| <p><b>Section:</b> 26.4.1.3 [rand.req.eng] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Charles Karney <b>Date:</b> 2007-05-15</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.req.eng">issues</a> in [rand.req.eng].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Section 26.4.1.3 [rand.req.eng] Random number engine requirements: |
| </p> |
| |
| <p> |
| This change follows naturally from the proposed change to |
| <tt>seed_seq::randomize</tt> in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#677">677</a>. |
| </p> |
| |
| <p> |
| In table 104 the description of <tt>X(q)</tt> contains a special treatment of |
| the case <tt>q.size() == 0</tt>. This is undesirable for 4 reasons: |
| </p> |
| |
| <ol> |
| <li>It replicates the functionality provided by <tt>X()</tt>.</li> |
| <li>It leads to the possibility of a collision in the state provided |
| by some other <tt>X(q)</tt> with <tt>q.size() > 0</tt>.</li> |
| <li>It is inconsistent with the description of the <tt>X(q)</tt> in |
| paragraphs 26.4.3.1 [rand.eng.lcong] p5, 26.4.3.2 [rand.eng.mers] p8, and 26.4.3.3 [rand.eng.sub] p10 where |
| there is no special treatment of <tt>q.size() == 0</tt>.</li> |
| <li>The proposed replacement for <tt>seed_seq::randomize</tt> given above |
| allows for the case <tt>q.size() == 0</tt>.</li> |
| </ol> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="679"></a>679. resize parameter by value</h3> |
| <p><b>Section:</b> 23.2 [sequences] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-06-11</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The C++98 standard specifies that one member function alone of the containers |
| passes its parameter (<tt>T</tt>) by value instead of by const reference: |
| </p> |
| |
| <blockquote><pre>void resize(size_type sz, T c = T()); |
| </pre></blockquote> |
| |
| <p> |
| This fact has been discussed / debated repeatedly over the years, the first time |
| being even before C++98 was ratified. The rationale for passing this parameter by |
| value has been: |
| </p> |
| |
| <blockquote> |
| <p> |
| So that self referencing statements are guaranteed to work, for example: |
| </p> |
| <blockquote><pre>v.resize(v.size() + 1, v[0]); |
| </pre></blockquote> |
| </blockquote> |
| |
| <p> |
| However this rationale is not convincing as the signature for <tt>push_back</tt> is: |
| </p> |
| |
| <blockquote><pre>void push_back(const T& x); |
| </pre></blockquote> |
| |
| <p> |
| And <tt>push_back</tt> has similar semantics to <tt>resize</tt> (append). |
| And <tt>push_back</tt> must also work in the self referencing case: |
| </p> |
| |
| <blockquote><pre>v.push_back(v[0]); // must work |
| </pre></blockquote> |
| |
| <p> |
| The problem with passing <tt>T</tt> by value is that it can be significantly more |
| expensive than passing by reference. The converse is also true, however when it is |
| true it is usually far less dramatic (e.g. for scalar types). |
| </p> |
| |
| <p> |
| Even with move semantics available, passing this parameter by value can be expensive. |
| Consider for example <tt>vector<vector<int>></tt>: |
| </p> |
| |
| <blockquote><pre>std::vector<int> x(1000); |
| std::vector<std::vector<int>> v; |
| ... |
| v.resize(v.size()+1, x); |
| </pre></blockquote> |
| |
| <p> |
| In the pass-by-value case, <tt>x</tt> is copied once to the parameter of |
| <tt>resize</tt>. And then internally, since the code can not know at compile |
| time by how much <tt>resize</tt> is growing the <tt>vector</tt>, <tt>x</tt> is |
| usually copied (not moved) a second time from <tt>resize</tt>'s parameter into its proper place |
| within the <tt>vector</tt>. |
| </p> |
| |
| <p> |
| With pass-by-const-reference, the <tt>x</tt> in the above example need be copied |
| only once. In this case, <tt>x</tt> has an expensive copy constructor and so any |
| copies that can be saved represents a significant savings. |
| </p> |
| |
| <p> |
| If we can be efficient for <tt>push_back</tt>, we should be efficient for <tt>resize</tt> |
| as well. The resize taking a reference parameter has been coded and shipped in the |
| CodeWarrior library with no reports of problems which I am aware of. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 23.2.2 [deque], p2: |
| </p> |
| |
| <blockquote><pre>class deque { |
| ... |
| void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| <p> |
| Change 23.2.2.2 [deque.capacity], p3: |
| </p> |
| |
| <blockquote><pre>void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| <p> |
| Change 23.2.4 [list], p2: |
| </p> |
| |
| <blockquote><pre>class list { |
| ... |
| void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| <p> |
| Change 23.2.4.2 [list.capacity], p3: |
| </p> |
| |
| <blockquote><pre>void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| <p> |
| Change 23.2.6 [vector], p2: |
| </p> |
| |
| <blockquote><pre>class vector { |
| ... |
| void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| <p> |
| Change 23.2.6.2 [vector.capacity], p11: |
| </p> |
| |
| <blockquote><pre>void resize(size_type sz, <ins>const </ins>T<ins>&</ins> c); |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="680"></a>680. move_iterator operator-> return</h3> |
| <p><b>Section:</b> 24.4.3.1 [move.iterator] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-06-11</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>move_iterator</tt>'s <tt>operator-></tt> return type <tt>pointer</tt> |
| does not consistently match the type which is returned in the description |
| in 24.4.3.3.5 [move.iter.op.ref]. |
| </p> |
| |
| <blockquote><pre>template <class Iterator> |
| class move_iterator { |
| public: |
| ... |
| typedef typename iterator_traits<Iterator>::pointer pointer; |
| ... |
| pointer operator->() const {return current;} |
| ... |
| private: |
| Iterator current; // exposition only |
| }; |
| </pre></blockquote> |
| |
| |
| <p> |
| There are two possible fixes. |
| </p> |
| |
| <ol> |
| <li><tt>pointer operator->() const {return &*current;}</tt></li> |
| <li><tt>typedef Iterator pointer;</tt></li> |
| </ol> |
| |
| <p> |
| The first solution is the one chosen by <tt>reverse_iterator</tt>. A potential |
| disadvantage of this is it may not work well with iterators which return a |
| proxy on dereference and that proxy has overloaded <tt>operator&()</tt>. Proxy |
| references often need to overloaad <tt>operator&()</tt> to return a proxy |
| pointer. That proxy pointer may or may not be the same type as the iterator's |
| <tt>pointer</tt> type. |
| </p> |
| |
| <p> |
| By simply returning the <tt>Iterator</tt> and taking advantage of the fact that |
| the language forwards calls to <tt>operator-></tt> automatically until it |
| finds a non-class type, the second solution avoids the issue of an overloaded |
| <tt>operator&()</tt> entirely. |
| </p> |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the synopsis in 24.4.3.1 [move.iterator]: |
| </p> |
| |
| <blockquote><pre>typedef <del>typename iterator_traits<</del>Iterator<del>>::pointer</del> pointer; |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="681"></a>681. Operator functions impossible to compare are defined in [re.submatch.op]</h3> |
| <p><b>Section:</b> 28.9.2 [re.submatch.op] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Nozomu Katoo <b>Date:</b> 2007-05-27</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In 28.9.2 [re.submatch.op] of N2284, |
| operator functions numbered 31-42 seem impossible to compare. E.g.: |
| </p> |
| |
| <blockquote> |
| <pre>template <class BiIter> |
| bool operator==(typename iterator_traits<BiIter>::value_type const& lhs, |
| const sub_match<BiIter>& rhs); |
| </pre> |
| <blockquote> |
| <p> |
| -31- <i>Returns:</i> <tt>lhs == rhs.str()</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| When <tt>char*</tt> is used as <tt>BiIter</tt>, <tt>iterator_traits<BiIter>::value_type</tt> would be |
| <tt>char</tt>, so that <tt>lhs == rhs.str()</tt> ends up comparing a <tt>char</tt> value and an object |
| of <tt>std::basic_string<char></tt>. However, the behaviour of comparison between |
| these two types is not defined in 21.3.8 [string.nonmembers] of N2284. |
| This applies when <tt>wchar_t*</tt> is used as <tt>BiIter</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2409.pdf">N2409</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="682"></a>682. basic_regex ctor takes InputIterator or ForwardIterator?</h3> |
| <p><b>Section:</b> 28.8.2 [re.regex.construct] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Eric Niebler <b>Date:</b> 2007-06-03</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Looking at N2284, 28.8 [re.regex], p3 <tt>basic_regex</tt> class template synopsis shows this |
| constructor: |
| </p> |
| <blockquote><pre>template <class InputIterator> |
| basic_regex(InputIterator first, InputIterator last, |
| flag_type f = regex_constants::ECMAScript); |
| </pre></blockquote> |
| |
| <p> |
| In 28.8.2 [re.regex.construct], p15, the constructor appears with this signature: |
| </p> |
| |
| <blockquote><pre>template <class ForwardIterator> |
| basic_regex(ForwardIterator first, ForwardIterator last, |
| flag_type f = regex_constants::ECMAScript); |
| </pre></blockquote> |
| |
| <p> |
| <tt>ForwardIterator</tt> is probably correct, so the synopsis is wrong. |
| </p> |
| |
| <p><i>[ |
| John adds: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| I think either could be implemented? Although an input iterator would |
| probably require an internal copy of the string being made. |
| </p> |
| <p> |
| I have no strong feelings either way, although I think my original intent |
| was <tt>InputIterator</tt>. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2409.pdf">N2409</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2409 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="685"></a>685. reverse_iterator/move_iterator difference has invalid signatures</h3> |
| <p><b>Section:</b> 24.4.1.3.19 [reverse.iter.opdiff], 24.4.3.3.14 [move.iter.nonmember] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Bo Persson <b>Date:</b> 2007-06-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In C++03 the difference between two <tt>reverse_iterators</tt> |
| </p> |
| <blockquote><pre>ri1 - ri2 |
| </pre></blockquote> |
| <p> |
| is possible to compute only if both iterators have the same base |
| iterator. The result type is the <tt>difference_type</tt> of the base iterator. |
| </p> |
| <p> |
| In the current draft, the operator is defined as 24.4.1.3.19 [reverse.iter.opdiff] |
| </p> |
| <blockquote><pre>template<class Iterator1, class Iterator2> |
| typename reverse_iterator<Iterator>::difference_type |
| operator-(const reverse_iterator<Iterator1>& x, |
| const reverse_iterator<Iterator2>& y); |
| </pre></blockquote> |
| <p> |
| The return type is the same as the C++03 one, based on the no longer |
| present <tt>Iterator</tt> template parameter. |
| </p> |
| <p> |
| Besides being slightly invalid, should this operator work only when |
| <tt>Iterator1</tt> and <tt>Iterator2</tt> has the same <tt>difference_type</tt>? Or should the |
| implementation choose one of them? Which one? |
| </p> |
| <p> |
| The same problem now also appears in <tt>operator-()</tt> for <tt>move_iterator</tt> |
| 24.4.3.3.14 [move.iter.nonmember]. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the synopsis in 24.4.1.1 [reverse.iterator]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Iterator1, class Iterator2> |
| <del>typename reverse_iterator<Iterator>::difference_type</del> <ins>auto</ins> operator-( |
| const reverse_iterator<Iterator1>& x, |
| const reverse_iterator<Iterator2>& y)<ins> -> decltype(y.current - x.current)</ins>; |
| </pre> |
| </blockquote> |
| |
| <p> |
| Change 24.4.1.3.19 [reverse.iter.opdiff]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Iterator1, class Iterator2> |
| <del>typename reverse_iterator<Iterator>::difference_type</del> <ins>auto</ins> operator-( |
| const reverse_iterator<Iterator1>& x, |
| const reverse_iterator<Iterator2>& y)<ins> -> decltype(y.current - x.current)</ins>; |
| </pre> |
| <blockquote> |
| <p> |
| <i>Returns:</i> <tt>y.current - x.current</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| <p> |
| Change the synopsis in 24.4.3.1 [move.iterator]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Iterator1, class Iterator2> |
| <del>typename move_iterator<Iterator>::difference_type</del> <ins>auto</ins> operator-( |
| const move_iterator<Iterator1>& x, |
| const move_iterator<Iterator2>& y)<ins> -> decltype(x.base() - y.base())</ins>; |
| </pre> |
| </blockquote> |
| |
| <p> |
| Change 24.4.3.3.14 [move.iter.nonmember]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Iterator1, class Iterator2> |
| <del>typename move_iterator<Iterator>::difference_type</del> <ins>auto</ins> operator-( |
| const move_iterator<Iterator1>& x, |
| const move_iterator<Iterator2>& y)<ins> -> decltype(x.base() - y.base())</ins>; |
| </pre> |
| <blockquote> |
| <p> |
| <i>Returns:</i> <tt>x.base() - y.base()</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[ |
| Pre Bellevue: This issue needs to wait until the <tt>auto -> return</tt> language feature |
| goes in. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="687"></a>687. shared_ptr conversion constructor not constrained</h3> |
| <p><b>Section:</b> 20.7.12.2.1 [util.smartptr.shared.const], 20.7.12.3.1 [util.smartptr.weak.const] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2007-05-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared.const">issues</a> in [util.smartptr.shared.const].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Since all conversions from <tt>shared_ptr<T></tt> to <tt>shared_ptr<U></tt> have the same |
| rank regardless of the relationship between <tt>T</tt> and <tt>U</tt>, reasonable user |
| code that works with raw pointers fails with <tt>shared_ptr</tt>: |
| </p> |
| |
| <blockquote><pre>void f( shared_ptr<void> ); |
| void f( shared_ptr<int> ); |
| |
| int main() |
| { |
| f( shared_ptr<double>() ); // ambiguous |
| } |
| </pre></blockquote> |
| |
| <p> |
| Now that we officially have <tt>enable_if</tt>, we can constrain the constructor |
| and the corresponding assignment operator to only participate in the |
| overload resolution when the pointer types are compatible. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.7.12.2.1 [util.smartptr.shared.const], change: |
| </p> |
| |
| <blockquote><p> |
| -14- <i>Requires:</i> <del>For the second constructor</del> <ins>The |
| second constructor shall not participate in the overload resolution |
| unless</ins> <tt>Y*</tt> <del>shall be</del> <ins>is implicitly</ins> convertible |
| to <tt>T*</tt>. |
| </p></blockquote> |
| |
| <p> |
| In 20.7.12.3.1 [util.smartptr.weak.const], change: |
| </p> |
| |
| <blockquote> |
| <pre><del>template<class Y> weak_ptr(shared_ptr<Y> const& r);</del> |
| <del>weak_ptr(weak_ptr const& r);</del> |
| <del>template<class Y> weak_ptr(weak_ptr<Y> const& r);</del> |
| <ins>weak_ptr(weak_ptr const& r);</ins> |
| <ins>template<class Y> weak_ptr(weak_ptr<Y> const& r);</ins> |
| <ins>template<class Y> weak_ptr(shared_ptr<Y> const& r);</ins> |
| </pre> |
| <blockquote><p> |
| -4- <i>Requires:</i> <del>For</del> <del>t</del><ins>T</ins>he second and |
| third constructors<del>,</del> <ins>shall not participate in the |
| overload resolution unless</ins> <tt>Y*</tt> <del>shall be</del> |
| <ins>is implicitly</ins> convertible to <tt>T*</tt>. |
| </p></blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="689"></a>689. reference_wrapper constructor overly constrained</h3> |
| <p><b>Section:</b> 20.6.5.1 [refwrap.const] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2007-05-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#refwrap.const">issues</a> in [refwrap.const].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The constructor of <tt>reference_wrapper</tt> is currently <tt>explicit</tt>. The primary |
| motivation behind this is the safety problem with respect to rvalues, |
| which is addressed by the proposed resolution of the previous issue. |
| Therefore we should consider relaxing the requirements on the |
| constructor since requests for the implicit conversion keep resurfacing. |
| </p> |
| <p> |
| Also please see the thread starting at c++std-lib-17398 for some good discussion on this subject. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove the <tt>explicit</tt> from the constructor of <tt>reference_wrapper</tt>. If the |
| proposed resolution of the previous issue is accepted, remove the |
| <tt>explicit</tt> from the <tt>T&&</tt> constructor as well to keep them in sync. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="693"></a>693. <code>std::bitset::all()</code> missing</h3> |
| <p><b>Section:</b> 23.3.5 [template.bitset] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-06-22</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#template.bitset">issues</a> in [template.bitset].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The <code>bitset</code> class template provides the member function |
| <code>any()</code> to determine whether an object of the type has any |
| bits set, and the member function <code>none()</code> to determine |
| whether all of an object's bits are clear. However, the template does |
| not provide a corresponding function to discover whether a |
| <code>bitset</code> object has all its bits set. While it is |
| possible, even easy, to obtain this information by comparing the |
| result of <code>count()</code> with the result of <code>size()</code> |
| for equality (i.e., via <code>b.count() == b.size()</code>) the |
| operation is less efficient than a member function designed |
| specifically for that purpose could be. (<code>count()</code> must |
| count all non-zero bits in a <code>bitset</code> a word at a time |
| while <code>all()</code> could stop counting as soon as it encountered |
| the first word with a zero bit). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a declaration of the new member function <code>all()</code> to the |
| defintion of the <code>bitset</code> template in 23.3.5 [template.bitset], p1, |
| right above the declaration of <code>any()</code> as shown below: |
| </p> |
| |
| <blockquote><pre>bool operator!=(const bitset<N>& rhs) const; |
| bool test(size_t pos) const; |
| <ins>bool all() const;</ins> |
| bool any() const; |
| bool none() const; |
| </pre></blockquote> |
| |
| <p> |
| Add a description of the new member function to the end of 23.3.5.2 [bitset.members] with the following text: |
| </p> |
| <blockquote><p> |
| <code>bool all() const;</code> |
| </p> |
| <blockquote> |
| <i>Returns</i>: <code>count() == size()</code>. |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| In addition, change the description of <code>any()</code> and |
| <code>none()</code> for consistency with <code>all()</code> as |
| follows: |
| </p> |
| <blockquote><p> |
| <code>bool any() const;</code> |
| </p> |
| <blockquote> |
| <p> |
| <i>Returns</i>: <del><code>true</code> if any bit in <code>*this</code> |
| is one</del><ins><code>count() != 0</code></ins>. |
| </p> |
| </blockquote> |
| <p> |
| <code>bool none() const;</code> |
| </p> |
| <blockquote> |
| <p> |
| <i>Returns</i>: <del><code>true</code> if no bit in <code>*this</code> |
| is one</del><ins><code>count() == 0</code></ins>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="694"></a>694. <code>std::bitset</code> and <code>long long</code></h3> |
| <p><b>Section:</b> 23.3.5 [template.bitset] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-06-22</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#template.bitset">issues</a> in [template.bitset].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Objects of the <code>bitset</code> class template specializations can |
| be constructed from and explicitly converted to values of the widest |
| C++ integer type, <code>unsigned long</code>. With the introduction |
| of <code>long long</code> into the language the template should be |
| enhanced to make it possible to interoperate with values of this type |
| as well, or perhaps <code>uintmax_t</code>. See c++std-lib-18274 for |
| a brief discussion in support of this change. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| For simplicity, instead of adding overloads for <code>unsigned long |
| long</code> and dealing with possible ambiguities in the spec, replace |
| the <code>bitset</code> ctor that takes an <code>unsigned long</code> |
| argument with one taking <code>unsigned long long</code> in the |
| definition of the template as shown below. (The standard permits |
| implementations to add overloads on other integer types or employ |
| template tricks to achieve the same effect provided they don't cause |
| ambiguities or changes in behavior.) |
| </p> |
| <blockquote> |
| <pre>// [bitset.cons] constructors: |
| bitset(); |
| bitset(unsigned <ins>long</ins> long val); |
| template<class charT, class traits, class Allocator> |
| explicit bitset( |
| const basic_string<charT,traits,Allocator>& str, |
| typename basic_string<charT,traits,Allocator>::size_type pos = 0, |
| typename basic_string<charT,traits,Allocator>::size_type n = |
| basic_string<charT,traits,Allocator>::npos); |
| </pre> |
| </blockquote> |
| <p> |
| Make a corresponding change in 23.3.5.1 [bitset.cons], p2: |
| </p> |
| <blockquote> |
| <p> |
| <code>bitset(unsigned <ins>long</ins> long val);</code> |
| </p> |
| <blockquote> |
| <i>Effects</i>: Constructs an object of class bitset<N>, |
| initializing the first <code><i>M</i></code> bit positions to the |
| corresponding bit values in <code><i>val</i></code>. |
| <code><i>M</i></code> is the smaller of <code><i>N</i></code> and the |
| number of bits in the value representation (section [basic.types]) of |
| <code>unsigned <ins> long</ins> long</code>. If <code><i>M</i> < |
| <i>N</i></code> <ins>is <code>true</code></ins>, the remaining bit |
| positions are initialized to zero. |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Additionally, introduce a new member function <code>to_ullong()</code> |
| to make it possible to convert <code>bitset</code> to values of the |
| new type. Add the following declaration to the definition of the |
| template, immediate after the declaration of <code>to_ulong()</code> |
| in 23.3.5 [template.bitset], p1, as shown below: |
| </p> |
| <blockquote> |
| <pre>// element access: |
| bool operator[](size_t pos) const; // for b[i]; |
| reference operator[](size_t pos); // for b[i]; |
| unsigned long to_ulong() const; |
| <ins>unsigned long long to_ullong() const;</ins> |
| template <class charT, class traits, class Allocator> |
| basic_string<charT, traits, Allocator> to_string() const; |
| </pre> |
| </blockquote> |
| <p> |
| And add a description of the new member function to 23.3.5.2 [bitset.members], |
| below the description of the existing <code>to_ulong()</code> (if |
| possible), with the following text: |
| </p> |
| <blockquote> |
| <p> |
| <code>unsigned long long to_ullong() const;</code> |
| </p> |
| <blockquote> |
| <i>Throws</i>: <code>overflow_error</code> if the integral value |
| <code><i>x</i></code> corresponding to the bits in <code>*this</code> |
| cannot be represented as type <code>unsigned long long</code>. |
| </blockquote> |
| <blockquote> |
| <i>Returns:</i> <code><i>x</i></code>. |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="695"></a>695. ctype<char>::classic_table() not accessible</h3> |
| <p><b>Section:</b> 22.2.1.3 [facet.ctype.special] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Martin Sebor <b>Date:</b> 2007-06-22</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The <code>ctype<char>::classic_table()</code> static member |
| function returns a pointer to an array of const |
| <code>ctype_base::mask</code> objects (enums) that contains |
| <code>ctype<char>::table_size</code> elements. The table |
| describes the properties of the character set in the "C" locale (i.e., |
| whether a character at an index given by its value is alpha, digit, |
| punct, etc.), and is typically used to initialize the |
| <code>ctype<char></code> facet in the classic "C" locale (the |
| protected <code>ctype<char></code> member function |
| <code>table()</code> then returns the same value as |
| <code>classic_table()</code>). |
| </p> |
| <p> |
| However, while <code>ctype<char>::table_size</code> (the size of |
| the table) is a public static const member of the |
| <code>ctype<char></code> specialization, the |
| <code>classic_table()</code> static member function is protected. That |
| makes getting at the classic data less than convenient (i.e., one has |
| to create a whole derived class just to get at the masks array). It |
| makes little sense to expose the size of the table in the public |
| interface while making the table itself protected, especially when the |
| table is a constant object. |
| </p> |
| <p> |
| The same argument can be made for the non-static protected member |
| function <code>table()</code>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Make the <code>ctype<char>::classic_table()</code> and |
| <code>ctype<char>::table()</code> member functions public by |
| moving their declarations into the public section of the definition of |
| specialization in 22.2.1.3 [facet.ctype.special] as shown below: |
| </p> |
| <blockquote> |
| <pre> static locale::id id; |
| static const size_t table_size = IMPLEMENTATION_DEFINED; |
| <del>protected:</del> |
| const mask* table() const throw(); |
| static const mask* classic_table() throw(); |
| <ins>protected:</ins> |
| |
| ~ctype(); // virtual |
| virtual char do_toupper(char c) const; |
| </pre> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="699"></a>699. N2111 changes min/max</h3> |
| <p><b>Section:</b> 26.4 [rand] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger <b>Date:</b> 2007-07-01</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand">issues</a> in [rand].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2111.pdf">N2111</a> |
| changes <tt>min/max</tt> in several places in random from member |
| functions to static data members. I believe this introduces |
| a needless backward compatibility problem between C++0X and |
| TR1. I'd like us to find new names for the static data members, |
| or perhaps change <tt>min/max</tt> to <tt>constexpr</tt>s in C++0X. |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="700"></a>700. N1856 defines struct <tt>identity</tt></h3> |
| <p><b>Section:</b> 20.2.2 [forward] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger <b>Date:</b> 2007-07-01</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#forward">active issues</a> in [forward].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#forward">issues</a> in [forward].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1856.html">N1856</a> |
| defines struct <tt>identity</tt> in <tt><utility></tt> which clashes with |
| the traditional definition of struct <tt>identity</tt> in <tt><functional></tt> |
| (not standard, but a common extension from old STL). Be nice |
| if we could avoid this name clash for backward compatibility. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 20.2.2 [forward]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class T> struct identity |
| { |
| typedef T type; |
| <ins>const T& operator()(const T& x) const;</ins> |
| }; |
| </pre> |
| <blockquote> |
| <pre><ins>const T& operator()(const T& x) const;</ins> |
| </pre> |
| <blockquote> |
| <p> |
| <ins><i>Returns:</i> <tt>x</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="703"></a>703. <tt>map::at()</tt> need a complexity specification</h3> |
| <p><b>Section:</b> 23.3.1.2 [map.access] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Joe Gottman <b>Date:</b> 2007-07-03</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#map.access">issues</a> in [map.access].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>map::at()</tt> need a complexity specification. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following to the specification of <tt>map::at()</tt>, 23.3.1.2 [map.access]: |
| </p> |
| <blockquote> |
| <p> |
| <i>Complexity:</i> logarithmic. |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="705"></a>705. type-trait <tt>decay</tt> incompletely specified</h3> |
| <p><b>Section:</b> 20.5.7 [meta.trans.other] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thorsten Ottosen <b>Date:</b> 2007-07-08</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#meta.trans.other">active issues</a> in [meta.trans.other].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#meta.trans.other">issues</a> in [meta.trans.other].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current working draft has a type-trait <tt>decay</tt> in 20.5.7 [meta.trans.other]. |
| </p> |
| |
| <p> |
| Its use is to turn C++03 pass-by-value parameters into efficient C++0x |
| pass-by-rvalue-reference parameters. However, the current definition |
| introduces an incompatible change where the cv-qualification of the |
| parameter type is retained. The deduced type should loose such |
| cv-qualification, as pass-by-value does. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.5.7 [meta.trans.other] change the last sentence: |
| </p> |
| |
| <blockquote><p> |
| Otherwise the member typedef <tt>type</tt> equals <tt><ins>remove_cv<</ins>U<ins>>::type</ins></tt>. |
| </p></blockquote> |
| |
| <p> |
| In 20.4.1.3 [tuple.creation]/1 change: |
| </p> |
| |
| <blockquote><p> |
| <del>where each <tt>Vi</tt> in <tt>VTypes</tt> is <tt>X&</tt> if, for the |
| corresponding type <tt>Ti</tt> in <tt>Types</tt>, |
| <tt>remove_cv<remove_reference<Ti>::type>::type</tt> equals |
| <tt>reference_wrapper<X></tt>, otherwise <tt>Vi</tt> is |
| <tt>decay<Ti>::type</tt>.</del> |
| <ins>Let <tt>Ui</tt> be <tt>decay<Ti>::type</tt> for each |
| <tt>Ti</tt> in <tt>Types</tt>. Then each <tt>Vi</tt> in <tt>VTypes</tt> |
| is <tt>X&</tt> if <tt>Ui</tt> equals |
| <tt>reference_wrapper<X></tt>, otherwise <tt>Vi</tt> is |
| <tt>Ui</tt>.</ins> |
| </p></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="706"></a>706. <tt>make_pair()</tt> should behave as <tt>make_tuple()</tt> wrt. <tt>reference_wrapper()</tt></h3> |
| <p><b>Section:</b> 20.2.3 [pairs] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thorsten Ottosen <b>Date:</b> 2007-07-08</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#pairs">issues</a> in [pairs].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current draft has <tt>make_pair()</tt> in 20.2.3 [pairs]/16 |
| and <tt>make_tuple()</tt> in 20.4.1.3 [tuple.creation]. |
| <tt>make_tuple()</tt> detects the presence of |
| <tt>reference_wrapper<X></tt> arguments and "unwraps" the reference in |
| such cases. <tt>make_pair()</tt> would OTOH create a |
| <tt>reference_wrapper<X></tt> member. I suggest that the two |
| functions are made to behave similar in this respect to minimize |
| confusion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.2 [utility] change the synopsis for make_pair() to read |
| </p> |
| |
| <blockquote><pre>template <class T1, class T2> |
| pair<<del>typename decay<T1>::type</del> <ins>V1</ins>, <del>typename decay<T2>::type</del> <ins>V2</ins>> make_pair(T1&&, T2&&); |
| </pre></blockquote> |
| |
| <p> |
| In 20.2.3 [pairs]/16 change the declaration to match the above synopsis. |
| Then change the 20.2.3 [pairs]/17 to: |
| </p> |
| |
| <blockquote> |
| <p> |
| <i>Returns:</i> <tt>pair<<del>typename decay<T1>::type</del> <ins>V1</ins>,<del>typename decay<T2>::type</del> <ins>V2</ins>>(forward<T1>(x),forward<T2>(y))</tt> <ins>where <tt>V1</tt> and |
| <tt>V2</tt> are determined as follows: Let <tt>Ui</tt> be |
| <tt>decay<Ti>::type</tt> for each <tt>Ti</tt>. Then each |
| <tt>Vi</tt> is <tt>X&</tt> if <tt>Ui</tt> equals |
| <tt>reference_wrapper<X></tt>, otherwise <tt>Vi</tt> is |
| <tt>Ui</tt>.</ins> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="710"></a>710. Missing postconditions</h3> |
| <p><b>Section:</b> 20.7.12.2 [util.smartptr.shared] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Peter Dimov <b>Date:</b> 2007-08-24</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#util.smartptr.shared">active issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#util.smartptr.shared">issues</a> in [util.smartptr.shared].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| A discussion on |
| <a href="http://groups.google.com/group/comp.std.c++/browse_frm/thread/8e89dceb35cd7971">comp.std.c++</a> |
| has identified a contradiction in the <tt>shared_ptr</tt> specification. |
| The <tt>shared_ptr</tt> move constructor and the cast functions are |
| missing postconditions for the <tt>get()</tt> accessor. |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Move to "ready", adopting the first (Peter's) proposed resolution. |
| </p> |
| <p> |
| Note to the project editor: there is an editorial issue here. The |
| wording for the postconditions of the casts is slightly awkward, and the |
| editor should consider rewording "If w is the return value...", e. g. as |
| "For a return value w...". |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to 20.7.12.2.1 [util.smartptr.shared.const]: |
| </p> |
| |
| <blockquote> |
| <pre>shared_ptr(shared_ptr&& r); |
| template<class Y> shared_ptr(shared_ptr<Y>&& r); |
| </pre> |
| <blockquote> |
| <p> |
| <i>Postconditions:</i> <tt>*this</tt> shall contain the old value of <tt>r</tt>. <tt>r</tt> |
| shall be empty. <ins><tt>r.get() == 0</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Add to 20.7.12.2.10 [util.smartptr.shared.cast]: |
| </p> |
| |
| <blockquote> |
| <pre>template<class T, class U> shared_ptr<T> static_pointer_cast(shared_ptr<U> const& r); |
| </pre> |
| <blockquote> |
| <p> |
| <ins><i>Postconditions:</i> If <tt>w</tt> is the return value, |
| <tt>w.get() == static_cast<T*>(r.get()) && w.use_count() == r.use_count()</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <blockquote> |
| <pre>template<class T, class U> shared_ptr<T> dynamic_pointer_cast(shared_ptr<U> const& r); |
| </pre> |
| <blockquote> |
| <p> |
| <ins><i>Postconditions:</i> If <tt>w</tt> is the return value, <tt>w.get() == dynamic_cast<T*>(r.get())</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <blockquote> |
| <pre>template<class T, class U> shared_ptr<T> const_pointer_cast(shared_ptr<U> const& r); |
| </pre> |
| <blockquote> |
| <p> |
| <ins><i>Postconditions:</i> If <tt>w</tt> is the return value, |
| <tt>w.get() == const_cast<T*>(r.get()) && w.use_count() == r.use_count()</tt>.</ins> |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Alberto Ganesh Barbati has written an |
| <a href="http://barbati.net/c++/shared_ptr.pdf">alternative proposal</a> |
| where he suggests (among other things) that the casts be respecified in terms of |
| the aliasing constructor as follows: |
| </p> |
| |
| <p> |
| Change 20.7.12.2.10 [util.smartptr.shared.cast]: |
| </p> |
| |
| <blockquote> |
| <p> |
| -2- <i>Returns:</i> <del>If <tt>r</tt> is empty, an <tt>empty |
| shared_ptr<T>;</tt> otherwise, a <tt>shared_ptr<T></tt> |
| object that stores <tt>static_cast<T*>(r.get())</tt> and shares ownership with |
| <tt>r</tt>.</del> <ins><tt>shared_ptr<T>(r, static_cast<T*>(r.get())</tt>.</ins> |
| </p> |
| </blockquote> |
| |
| <blockquote> |
| <p> |
| -6- <i>Returns:</i> |
| </p> |
| <ul> |
| <li><del>When <tt>dynamic_cast<T*>(r.get())</tt> returns a nonzero value, |
| a <tt>shared_ptr<T></tt> object that stores a copy |
| of it and <i>shares ownership</i> with <tt>r</tt>;</del></li> |
| <li><del>Otherwise, an <i>empty</i> <tt>shared_ptr<T></tt> object.</del></li> |
| <li><ins>If <tt>p = dynamic_cast<T*>(r.get())</tt> is a non-null pointer, <tt>shared_ptr<T>(r, p);</tt></ins></li> |
| <li><ins>Otherwise, <tt>shared_ptr<T>()</tt>.</ins></li> |
| </ul> |
| </blockquote> |
| |
| <blockquote> |
| <p> |
| -10- <i>Returns:</i> <del>If <tt>r</tt> is empty, an <tt>empty |
| shared_ptr<T>;</tt> otherwise, a <tt>shared_ptr<T></tt> |
| object that stores <tt>const_cast<T*>(r.get())</tt> and shares ownership with |
| <tt>r</tt>.</del> <ins><tt>shared_ptr<T>(r, const_cast<T*>(r.get())</tt>.</ins> |
| </p> |
| </blockquote> |
| |
| <p> |
| This takes care of the missing postconditions for the casts by bringing |
| in the aliasing constructor postcondition "by reference". |
| </p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="712"></a>712. <tt>seed_seq::size</tt> no longer useful</h3> |
| <p><b>Section:</b> 26.4.7.1 [rand.util.seedseq] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Marc Paterno <b>Date:</b> 2007-08-25</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| One of the motivations for incorporating <tt>seed_seq::size()</tt> |
| was to simplify the wording |
| in other parts of 26.4 [rand]. |
| As a side effect of resolving related issues, |
| all such references |
| to <tt>seed_seq::size()</tt> will have been excised. |
| More importantly, |
| the present specification is contradictory, |
| as "The number of 32-bit units the object can deliver" |
| is not the same as "the result of <tt>v.size()</tt>." |
| </p> |
| |
| <p> |
| See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2391.pdf">N2391</a> and |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a> |
| for some further discussion. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Adopt the proposed resolution in |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2423.pdf">N2423</a>. |
| </p> |
| |
| |
| <p><i>[ |
| Kona (2007): The LWG adopted the proposed resolution of N2423 for this issue. |
| The LWG voted to accelerate this issue to Ready status to be voted into the WP at Kona. |
| ]</i></p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="715"></a>715. <tt>minmax_element</tt> complexity is too lax</h3> |
| <p><b>Section:</b> 25.3.7 [alg.min.max] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Matt Austern <b>Date:</b> 2007-08-30</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#alg.min.max">issues</a> in [alg.min.max].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The complexity for <tt>minmax_element</tt> (25.3.7 [alg.min.max] par 16) says "At most <tt>max(2 * |
| (last - first ) - 2, 0)</tt> applications of the corresponding comparisons", |
| i.e. the worst case complexity is no better than calling <tt>min_element</tt> and |
| <tt>max_element</tt> separately. This is gratuitously inefficient. There is a |
| well known technique that does better: see section 9.1 of CLRS |
| (Introduction to Algorithms, by Cormen, Leiserson, Rivest, and Stein). |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 25.3.7 [alg.min.max] to: |
| </p> |
| |
| <blockquote> |
| <pre>template<class ForwardIterator> |
| pair<ForwardIterator, ForwardIterator> |
| minmax_element(ForwardIterator first , ForwardIterator last); |
| template<class ForwardIterator, class Compare> |
| pair<ForwardIterator, ForwardIterator> |
| minmax_element(ForwardIterator first , ForwardIterator last , Compare comp); |
| </pre> |
| <blockquote> |
| <p> |
| <i>Returns:</i> <tt>make_pair(m, M)</tt>, where <tt>m</tt> is |
| <del><tt>min_element(first, last)</tt> or <tt>min_element(first, last, |
| comp)</tt></del> <ins>the first iterator in <tt>[first, |
| last)</tt> such that no iterator in the range refers to a smaller element,</ins> and |
| <ins>where</ins> <tt>M</tt> is <del><tt>max_element(first, last)</tt> or |
| <tt>max_element(first, last, comp)</tt></del> <ins>the last iterator |
| in <tt>[first, last)</tt> such that no iterator in the range refers to a larger element</ins>. |
| </p> |
| <p> |
| <i>Complexity:</i> At most <del><tt>max(2 * (last - first ) - 2, 0)</tt></del> |
| <ins><tt>max(⌊(3/2) (N-1)⌋, 0)</tt></ins> applications of the |
| corresponding <del>comparisons</del> <ins>predicate, where <tt>N</tt> is <tt>distance(first, last)</tt></ins>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="722"></a>722. Missing [c.math] functions <tt>nanf</tt> and <tt>nanl</tt></h3> |
| <p><b>Section:</b> 26.7 [c.math] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2007-08-27</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#c.math">issues</a> in [c.math].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| In the listing of 26.7 [c.math], table 108: Header <tt><cmath></tt> synopsis I miss |
| the following C99 functions (from 7.12.11.2): |
| </p> |
| |
| <blockquote><pre>float nanf(const char *tagp); |
| long double nanl(const char *tagp); |
| </pre></blockquote> |
| |
| <p> |
| (Note: These functions cannot be overloaded and they are also not |
| listed anywhere else) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 26.7 [c.math], table 108, section "Functions", add <tt>nanf</tt> and <tt>nanl</tt> |
| just after the existing entry <tt>nan</tt>. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="740"></a>740. Please remove <tt>*_ptr<T[N]></tt></h3> |
| <p><b>Section:</b> 20.7.11.4 [unique.ptr.compiletime] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Herb Sutter <b>Date:</b> 2007-10-04</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Please don't provide <tt>*_ptr<T[N]></tt>. It doesn't enable any useful |
| bounds-checking (e.g., you could imagine that doing <tt>op++</tt> on a |
| <tt>shared_ptr<T[N]></tt> yields a <tt>shared_ptr<T[N-1]></tt>, but that promising path |
| immediately falters on <tt>op--</tt> which can't reliably dereference because we |
| don't know the lower bound). Also, most buffers you'd want to point to |
| don't have a compile-time known size. |
| </p> |
| |
| <p> |
| To enable any bounds-checking would require run-time information, with |
| the usual triplet: base (lower bound), current offset, and max offset |
| (upper bound). And I can sympathize with the point of view that you |
| wouldn't want to require this on <tt>*_ptr</tt> itself. But please let's not |
| follow the <tt><T[N]></tt> path, especially not with additional functions to |
| query the bounds etc., because this sets wrong user expectations by |
| embarking on a path that doesn't go all the way to bounds checking as it |
| seems to imply. |
| </p> |
| |
| <p> |
| If bounds checking is desired, consider a <tt>checked_*_ptr</tt> instead (e.g., |
| <tt>checked_shared_ptr</tt>). And make the interfaces otherwise identical so that |
| user code could easily <tt>#define/typedef</tt> between prepending <tt>checked_</tt> on |
| debug builds and not doing so on release builds (for example). |
| </p> |
| |
| <p> |
| Note that some may object that <tt>checked_*_ptr</tt> may seem to make the smart |
| pointer more like <tt>vector</tt>, and we don't want two ways to spell <tt>vector</tt>. I |
| don't agree, but if that were true that would be another reason to |
| remove <tt>*_ptr<T[N]></tt> which equally makes the smart pointer more like |
| <tt>std::array.</tt> :-) |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p>Suggestion that fixed-size array instantiations are going to fail at |
| compile time anyway (if we remove specialization) due to pointer decay, |
| at least that appears to be result from available compilers. |
| </p> |
| <p> |
| So concerns about about requiring static_assert seem unfounded. |
| </p> |
| <p>After a little more experimentation with compiler, it appears that |
| fixed size arrays would only work at all if we supply these explicit |
| specialization. So removing them appears less breaking than originally |
| thought. |
| </p> |
| <p> |
| straw poll unanimous move to Ready. |
| </p> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the synopsis under 20.7.11 [unique.ptr] p2: |
| </p> |
| |
| <blockquote><pre>... |
| template<class T> struct default_delete; |
| template<class T> struct default_delete<T[]>; |
| <del>template<class T, size_t N> struct default_delete<T[N]>;</del> |
| |
| template<class T, class D = default_delete<T>> class unique_ptr; |
| template<class T, class D> class unique_ptr<T[], D>; |
| <del>template<class T, class D, size_t N> class unique_ptr<T[N], D>;</del> |
| ... |
| </pre></blockquote> |
| |
| <p> |
| Remove the entire section 20.7.11.1.3 [unique.ptr.dltr.dflt2] <b><tt>default_delete<T[N]></tt></b>. |
| </p> |
| |
| <p> |
| Remove the entire section 20.7.11.4 [unique.ptr.compiletime] <b><tt>unique_ptr</tt> for array objects with a compile time length</b> |
| and its subsections: 20.7.11.4.1 [unique.ptr.compiletime.dtor], 20.7.11.4.2 [unique.ptr.compiletime.observers], |
| 20.7.11.4.3 [unique.ptr.compiletime.modifiers]. |
| </p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="743"></a>743. rvalue <tt>swap</tt> for <tt>shared_ptr</tt></h3> |
| <p><b>Section:</b> 20.7.12.2.9 [util.smartptr.shared.spec] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Howard Hinnant <b>Date:</b> 2007-10-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| When the LWG looked at <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#674">674</a> in Kona the following note was made: |
| </p> |
| |
| <blockquote><p> |
| We may need to open an issue to deal with the question of |
| whether <tt>shared_ptr</tt> needs an rvalue <tt>swap</tt>. |
| </p></blockquote> |
| |
| <p> |
| This issue was opened in response to that note. |
| </p> |
| |
| <p> |
| I believe allowing rvalue <tt>shared_ptr</tt>s to <tt>swap</tt> is both |
| appropriate, and consistent with how other library components are currently specified. |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Concern that the three signatures for swap is needlessly complicated, |
| but this issue merely brings shared_ptr into equal complexity with the |
| rest of the library. Will open a new issue for concern about triplicate |
| signatures. |
| </p> |
| <p> |
| Adopt issue as written. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the synopsis in 20.7.12.2 [util.smartptr.shared]: |
| </p> |
| |
| <blockquote><pre>void swap(shared_ptr&<ins>&</ins> r); |
| ... |
| template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b); |
| <ins>template<class T> void swap(shared_ptr<T>&& a, shared_ptr<T>& b); |
| template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>&& b);</ins> |
| </pre></blockquote> |
| |
| <p> |
| Change 20.7.12.2.4 [util.smartptr.shared.mod]: |
| </p> |
| |
| <blockquote><pre>void swap(shared_ptr&<ins>&</ins> r); |
| </pre></blockquote> |
| |
| <p> |
| Change 20.7.12.2.9 [util.smartptr.shared.spec]: |
| </p> |
| |
| <blockquote><pre>template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b); |
| <ins>template<class T> void swap(shared_ptr<T>&& a, shared_ptr<T>& b); |
| template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>&& b);</ins> |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="744"></a>744. What is the lifetime of an exception pointed to by an exception_ptr?</h3> |
| <p><b>Section:</b> 18.7.5 [propagation] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 2007-10-10</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#propagation">active issues</a> in [propagation].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#propagation">issues</a> in [propagation].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Without some lifetime guarantee, it is hard to know how this type can be |
| used. Very specifically, I don't see how the current wording would |
| guarantee and exception_ptr caught at the end of one thread could be safely |
| stored and rethrown in another thread - the original motivation for this |
| API. |
| </p> |
| <p> |
| (Peter Dimov agreed it should be clearer, maybe a non-normative note to |
| explain?) |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Agree the issue is real. |
| </p> |
| <p> |
| Intent is lifetime is similar to a shared_ptr (and we might even want to |
| consider explicitly saying that it is a shared_ptr< unspecified type >). |
| </p> |
| <p> |
| We expect that most implementations will use shared_ptr, and the |
| standard should be clear that the exception_ptr type is intended to be |
| something whose semantics are smart-pointer-like so that the user does |
| not need to worry about lifetime management. We still need someone to |
| draught those words - suggest emailing Peter Dimov. |
| </p> |
| <p> |
| Move to Open. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 18.7.5 [propagation]/7: |
| </p> |
| |
| <blockquote> |
| -7- Returns: An <tt>exception_ptr</tt> object that refers to the currently |
| handled exception or a copy of the currently handled exception, or a |
| null <tt>exception_ptr</tt> object if no exception is being handled. |
| <ins>The referenced object remains valid at least as long as there is an |
| <tt>exception_ptr</tt> that refers to it.</ins> |
| If the function needs to allocate memory and the attempt |
| fails, it returns an <tt>exception_ptr</tt> object that refers to an instance of |
| <tt>bad_alloc</tt>. It is unspecified whether the return values of two successive |
| calls to <tt>current_exception</tt> refer to the same exception object. [<i>Note:</i> |
| that is, it is unspecified whether <tt>current_exception</tt> creates a new copy |
| each time it is called. <i>--end note</i>] |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="746"></a>746. current_exception may fail with bad_alloc</h3> |
| <p><b>Section:</b> 18.7.5 [propagation] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 2007-10-10</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#propagation">active issues</a> in [propagation].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#propagation">issues</a> in [propagation].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| I understand that the attempt to copy an exception may run out of memory, |
| but I believe this is the only part of the standard that mandates failure |
| with specifically <tt>bad_alloc</tt>, as opposed to allowing an |
| implementation-defined type derived from <tt>bad_alloc</tt>. For instance, the Core |
| language for a failed new expression is: |
| </p> |
| <blockquote> |
| <p> |
| Any other allocation function that fails to allocate storage shall indicate |
| failure only by throwing an exception of a type that would match a handler |
| (15.3) of type <tt>std::bad_alloc</tt> (18.5.2.1). |
| </p> |
| </blockquote> |
| <p> |
| I think we should allow similar freedom here (or add a blanket |
| compatible-exception freedom paragraph in 17) |
| </p> |
| <p> |
| I prefer the clause 17 approach myself, and maybe clean up any outstanding |
| wording that could also rely on it. |
| </p> |
| <p> |
| Although filed against a specific case, this issue is a problem throughout |
| the library. |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Is issue bigger than library? |
| </p> |
| <p> |
| No - Core are already very clear about their wording, which is inspiration for the issue. |
| </p> |
| <p> |
| While not sold on the original 18.7.5 use case, the generalised 17.4.4.8 wording is the real issue. |
| </p> |
| <p> |
| Accept the broad view and move to ready |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following exemption clause to 17.4.4.9 [res.on.exception.handling]: |
| </p> |
| |
| <blockquote> |
| A function may throw a type not listed in its <i>Throws</i> clause so long as it is |
| derived from a class named in the <i>Throws</i> clause, and would be caught by an |
| exception handler for the base type. |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="749"></a>749. Currently <tt>has_nothrow_copy_constructor<T>::value</tt> is true if T has 'a' nothrow copy constructor.</h3> |
| <p><b>Section:</b> 20.5.4.3 [meta.unary.prop] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 2007-10-10</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#meta.unary.prop">issues</a> in [meta.unary.prop].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Unfortunately a class can have multiple copy constructors, and I believe to |
| be useful this trait should only return true is ALL copy constructors are |
| no-throw. |
| </p> |
| <p> |
| For instance: |
| </p> |
| <blockquote> |
| <pre>struct awkward { |
| awkward( const awkward & ) throw() {} |
| awkward( awkward & ) { throw "oops"; } }; |
| </pre> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 20.5.4.3 [meta.unary.prop]: |
| </p> |
| |
| <blockquote> |
| <pre>has_trivial_copy_constructor</pre> |
| <blockquote> |
| <tt>T</tt> is a trivial type (3.9) or a reference type or a class type <del>with a trivial copy constructor</del> |
| <ins>where all copy constructors are trivial</ins> (12.8). |
| </blockquote> |
| </blockquote> |
| |
| <blockquote> |
| <pre>has_trivial_assign</pre> |
| <blockquote> |
| <tt>T</tt> is neither <tt>const</tt> nor a reference type, and <tt>T</tt> is a trivial type (3.9) |
| or a class type <del>with a trivial copy assignment operator</del> <ins>where all copy assignment operators are trivial</ins> (12.8). |
| </blockquote> |
| </blockquote> |
| |
| <blockquote> |
| <pre>has_nothrow_copy_constructor</pre> |
| <blockquote> |
| <tt>has_trivial_copy_constructor<T>::value</tt> is <tt>true</tt> or <tt>T</tt> is a class type <del>with |
| a</del> <ins>where all</ins> copy constructor<ins>s</ins> <del>that is</del> <ins>are</ins> |
| known not to throw any exceptions or <tt>T</tt> is an |
| array of such a class type |
| </blockquote> |
| </blockquote> |
| |
| <blockquote> |
| <pre>has_nothrow_assign</pre> |
| <blockquote> |
| <tt>T</tt> is neither <tt>const</tt> nor a reference type, and |
| <tt>has_trivial_assign<T>::value</tt> is <tt>true</tt> or <tt>T</tt> is a class type <del>with a</del> |
| <ins>where all</ins> copy |
| assignment operator<ins>s</ins> tak<ins>e</ins><del>ing</del> an lvalue of type <tt>T</tt> that is known not to |
| throw any exceptions or <tt>T</tt> is an array of such a class type. |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="755"></a>755. <tt>std::vector</tt> and <tt>std:string</tt> lack explicit shrink-to-fit operations</h3> |
| <p><b>Section:</b> 23.2.6.2 [vector.capacity], 21.3.4 [string.capacity] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Beman Dawes <b>Date:</b> 2007-10-31</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#vector.capacity">issues</a> in [vector.capacity].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| A <tt>std::vector</tt> can be shrunk-to-fit via the swap idiom: |
| </p> |
| |
| <blockquote><pre>vector<int> v; |
| ... |
| v.swap(vector<int>(v)); // shrink to fit |
| </pre> |
| <blockquote><p> |
| or: |
| </p></blockquote> |
| <pre>vector<int>(v).swap(v); // shrink to fit |
| </pre> |
| <blockquote><p> |
| or: |
| </p></blockquote> |
| <pre>swap(v, vector<int>(v)); // shrink to fit |
| </pre> |
| </blockquote> |
| |
| <p> |
| A non-binding request for shrink-to-fit can be made to a <tt>std::string</tt> via: |
| </p> |
| |
| <blockquote><pre>string s; |
| ... |
| s.reserve(0); |
| </pre></blockquote> |
| |
| <p> |
| Neither of these is at all obvious to beginners, and even some |
| experienced C++ programmers are not aware that shrink-to-fit is |
| trivially available. |
| </p> |
| <p> |
| Lack of explicit functions to perform these commonly requested |
| operations makes vector and string less usable for non-experts. Because |
| the idioms are somewhat obscure, code readability is impaired. It is |
| also unfortunate that two similar vector-like containers use different |
| syntax for the same operation. |
| </p> |
| <p> |
| The proposed resolution addresses these concerns. The proposed function |
| takes no arguments to keep the solution simple and focused. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| To Class template basic_string 21.3 [basic.string] synopsis, |
| Class template vector 23.2.6 [vector] synopsis, and Class |
| vector<bool> 23.2.7 [vector.bool] synopsis, add: |
| </p> |
| |
| <blockquote><pre> |
| void shrink_to_fit(); |
| </pre></blockquote> |
| |
| <p> |
| To basic_string capacity 21.3.4 [string.capacity] and vector |
| capacity 23.2.6.2 [vector.capacity], add: |
| </p> |
| |
| <blockquote> |
| <pre>void shrink_to_fit(); |
| </pre> |
| <blockquote> |
| <i>Remarks:</i> <tt>shrink_to_fit</tt> is a non-binding request to reduce |
| <tt>capacity()</tt> to <tt>size()</tt>. [<i>Note:</i> The request is non-binding to |
| allow latitude for implementation-specific optimizations. |
| <i>-- end note</i>] |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[ |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#850">850</a> has been added to deal with this issue with respect to <tt>deque</tt>. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="759"></a>759. A reference is not an object</h3> |
| <p><b>Section:</b> 23.1 [container.requirements] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Jens Maurer <b>Date:</b> 2007-11-06</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 23.1 [container.requirements] says: |
| </p> |
| |
| <blockquote> |
| -12- Objects passed to member functions of a container as rvalue references shall not be elements of that container. No |
| diagnostic required. |
| </blockquote> |
| |
| <p> |
| A reference is not an object, but this sentence appears to claim so. |
| </p> |
| |
| <p> |
| What is probably meant here: |
| </p> |
| <blockquote> |
| An object bound to an rvalue |
| reference parameter of a member function of a container shall not be |
| an element of that container; no diagnostic required. |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 23.1 [container.requirements]: |
| </p> |
| |
| <blockquote> |
| -12- <del>Objects passed to member functions of a container as rvalue references shall not be elements</del> |
| <ins>An object bound to an rvalue |
| reference parameter of a member function of a container shall not be |
| an element</ins> |
| of that container<del>.</del><ins>;</ins> <del>N</del><ins>n</ins>o |
| diagnostic required. |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="761"></a>761. <tt>unordered_map</tt> needs an <tt>at()</tt> member function</h3> |
| <p><b>Section:</b> 23.4.1.2 [unord.map.elem] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Joe Gottman <b>Date:</b> 2007-11-15</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The new member function <tt>at()</tt> was recently added to <tt>std::map()</tt>. It acts |
| like <tt>operator[]()</tt>, except it throws an exception when the input key is |
| not found. It is useful when the <tt>map</tt> is <tt>const</tt>, the <tt>value_type</tt> of the |
| key doesn't have a default constructor, it is an error if the key is |
| not found, or the user wants to avoid accidentally adding an element to |
| the map. For exactly these same reasons, <tt>at()</tt> would be equally useful |
| in <tt>std::unordered_map</tt>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the following functions to the definition of <tt>unordered_map</tt> under "lookup" (23.4.1 [unord.map]): |
| </p> |
| |
| <blockquote><pre>mapped_type& at(const key_type& k); |
| const mapped_type &at(const key_type &k) const; |
| </pre></blockquote> |
| |
| <p> |
| Add the following definitions to 23.4.1.2 [unord.map.elem]: |
| </p> |
| |
| <blockquote> |
| <pre>mapped_type& at(const key_type& k); |
| const mapped_type &at(const key_type &k) const; |
| </pre> |
| <blockquote> |
| <p> |
| <i>Returns:</i> A reference to <tt>x.second</tt>, where <tt>x</tt> is the (unique) element |
| whose key is equivalent to <tt>k</tt>. |
| </p> |
| <p> |
| <i>Throws:</i> An exception object of type <tt>out_of_range</tt> if no such element |
| is present. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p><i>[ |
| Bellevue: Editorial note: the "(unique)" differs from map. |
| ]</i></p> |
| |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="766"></a>766. Inconsistent exception guarantees between ordered and unordered associative containers</h3> |
| <p><b>Section:</b> 23.1 [container.requirements], 23.1.5.1 [unord.req.except] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Ion Gaztañaga <b>Date:</b> 2007-12-22</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#container.requirements">active issues</a> in [container.requirements].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#container.requirements">issues</a> in [container.requirements].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| 23.1 [container.requirements]p10 states: |
| </p> |
| |
| <blockquote> |
| <p> |
| Unless otherwise specified (see 23.2.2.3 and 23.2.5.4) all container types defined in this clause meet the following |
| additional requirements: |
| </p> |
| <ul> |
| |
| <li>[...]</li> |
| |
| <li>no <tt>erase()</tt>, <tt>pop_back()</tt> or <tt>pop_front()</tt> function throws an exception.</li> |
| |
| </ul> |
| </blockquote> |
| |
| <p> |
| 23.2.2.3 [deque.modifiers] and 23.2.6.4 [vector.modifiers] offer |
| additional guarantees for <tt>deque</tt>/<tt>vector insert()</tt> and |
| <tt>erase()</tt> members. However, 23.1 [container.requirements]p10 |
| does not mention 23.1.5.1 [unord.req.except] that specifies exception |
| safety guarantees |
| for unordered containers. In addition, 23.1.5.1 [unord.req.except]p1 |
| offers the following guaratee for |
| <tt>erase()</tt>: |
| </p> |
| |
| <blockquote> |
| No <tt>erase()</tt> function throws an exception unless that exception |
| is thrown by the container's Hash or Pred object (if any). |
| </blockquote> |
| |
| <p> |
| Summary: |
| </p> |
| |
| <p> |
| According to 23.1 [container.requirements]p10 no |
| <tt>erase()</tt> function should throw an exception unless otherwise |
| specified. Although does not explicitly mention 23.1.5.1 [unord.req.except], this section offers additional guarantees |
| for unordered containers, allowing <tt>erase()</tt> to throw if |
| predicate or hash function throws. |
| </p> |
| |
| <p> |
| In contrast, associative containers have no exception safety guarantees |
| section so no <tt>erase()</tt> function should throw, <em>including |
| <tt>erase(k)</tt></em> that needs to use the predicate function to |
| perform its work. This means that the predicate of an associative |
| container is not allowed to throw. |
| </p> |
| |
| <p> |
| So: |
| </p> |
| |
| <ol> |
| <li> |
| <tt>erase(k)</tt> for associative containers is not allowed to throw. On |
| the other hand, <tt>erase(k)</tt> for unordered associative containers |
| is allowed to throw. |
| </li> |
| <li> |
| <tt>erase(q)</tt> for associative containers is not allowed to throw. On |
| the other hand, <tt>erase(q)</tt> for unordered associative containers |
| is allowed to throw if it uses the hash or predicate. |
| </li> |
| <li> |
| To fulfill 1), predicates of associative containers are not allowed to throw. |
| Predicates of unordered associative containers are allowed to throw. |
| </li> |
| <li> |
| 2) breaks a widely used programming pattern (flyweight pattern) for |
| unordered containers, where objects are registered in a global map in |
| their constructors and unregistered in their destructors. If <tt>erase(q)</tt> is |
| allowed to throw, the destructor of the object would need to rethrow the |
| exception or swallow it, leaving the object registered. |
| </li> |
| </ol> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Create a new sub-section of 23.1.4 [associative.reqmts] (perhaps [associative.req.except]) titled "Exception |
| safety guarantees". |
| </p> |
| |
| <blockquote> |
| <p> |
| 1 For associative containers, no <tt>clear()</tt> function throws an exception. |
| <tt>erase(k)</tt> does not throw an exception unless that exception is thrown by |
| the container's Pred object (if any). |
| </p> |
| |
| <p> |
| 2 For associative containers, if an exception is thrown by any operation |
| from within an <tt>insert()</tt> function inserting a single element, the |
| <tt>insert()</tt> function has no effect. |
| </p> |
| |
| <p> |
| 3 For associative containers, no <tt>swap</tt> function throws an exception |
| unless that exception is thrown by the copy constructor or copy |
| assignment operator of the container's Pred object (if any). |
| </p> |
| </blockquote> |
| |
| <p> |
| Change 23.1.5.1 [unord.req.except]p1: |
| </p> |
| |
| <blockquote> |
| For unordered associative containers, no <tt>clear()</tt> function |
| throws an exception. <del>No</del> <tt>erase(<ins>k</ins>)</tt> |
| <del>function</del> <ins>does not</ins> throw<del>s</del> an exception |
| unless that exception is thrown by the container's Hash or Pred object |
| (if any). |
| </blockquote> |
| |
| <p> |
| Change 23.1 [container.requirements]p10 to add references to new sections: |
| </p> |
| |
| <blockquote> |
| Unless otherwise specified (see [deque.modifiers]<ins>,</ins> |
| <del>and</del> [vector.modifiers]<ins>, [associative.req.except], |
| [unord.req.except]</ins>) all container types defined in this clause meet |
| the following additional requirements: |
| </blockquote> |
| |
| <p> |
| Change 23.1 [container.requirements]p10 referring to <tt>swap</tt>: |
| </p> |
| |
| <blockquote> |
| <ul> |
| <li> |
| no <tt>swap()</tt> function throws an exception<del> unless that exception is thrown |
| by the copy constructor or assignment operator of the container's |
| Compare object (if any; see [associative.reqmts])</del>. |
| </li> |
| </ul> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="768"></a>768. Typos in [atomics]?</h3> |
| <p><b>Section:</b> 29.3.3 [atomics.types.generic] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alberto Ganesh Barbati <b>Date:</b> 2007-12-28</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| in the latest publicly available draft, paper |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">N2641</a>, |
| in section 29.3.3 [atomics.types.generic], the following specialization of the template |
| <tt>atomic<></tt> is provided for pointers: |
| </p> |
| |
| <blockquote><pre>template <class T> struct atomic<T*> : atomic_address { |
| T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; |
| T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; |
| |
| atomic() = default; |
| constexpr explicit atomic(T); |
| atomic(const atomic&) = delete; |
| atomic& operator=(const atomic&) = delete; |
| |
| T* operator=(T*) volatile; |
| T* operator++(int) volatile; |
| T* operator--(int) volatile; |
| T* operator++() volatile; |
| T* operator--() volatile; |
| T* operator+=(ptrdiff_t) volatile; |
| T* operator-=(ptrdiff_t) volatile; |
| }; |
| </pre></blockquote> |
| |
| <p> |
| First of all, there is a typo in the non-default constructor which |
| should take a <tt>T*</tt> rather than a <tt>T</tt>. |
| </p> |
| |
| <p> |
| As you can see, the specialization redefine and therefore hide a few |
| methods from the base class <tt>atomic_address</tt>, namely <tt>fetch_add</tt>, <tt>fetch_sub</tt>, |
| <tt>operator=</tt>, <tt>operator+=</tt> and <tt>operator-=</tt>. That's good, but... what happened |
| to the other methods, in particular these ones: |
| </p> |
| |
| <blockquote><pre>void store(T*, memory_order = memory_order_seq_cst) volatile; |
| T* load( memory_order = memory_order_seq_cst ) volatile; |
| T* swap( T*, memory_order = memory_order_seq_cst ) volatile; |
| bool compare_swap( T*&, T*, memory_order, memory_order ) volatile; |
| bool compare_swap( T*&, T*, memory_order = memory_order_seq_cst ) volatile; |
| </pre></blockquote> |
| |
| <p> |
| By reading paper |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2427.html">N2427 "C++ Atomic Types and Operations"</a>, |
| I see that the |
| definition of the specialization <tt>atomic<T*></tt> matches the one in the |
| draft, but in the example implementation the methods <tt>load()</tt>, <tt>swap()</tt> |
| and <tt>compare_swap()</tt> are indeed present. |
| </p> |
| |
| <p> |
| Strangely, the example implementation does not redefine the method |
| <tt>store()</tt>. It's true that a <tt>T*</tt> is always convertible to <tt>void*</tt>, but not |
| hiding the <tt>void*</tt> signature from the base class makes the class |
| error-prone to say the least: it lets you assign pointers of any type to |
| a <tt>T*</tt>, without any hint from the compiler. |
| </p> |
| |
| <p> |
| Is there a true intent to remove them from the specialization or are |
| they just missing from the definition because of a mistake? |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| The proposed revisions are accepted. |
| </p> |
| <p> |
| Further discussion: why is the ctor labeled "constexpr"? Lawrence said |
| this permits the object to be statically initialized, and that's |
| important because otherwise there would be a race condition on |
| initialization. |
| </p> |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change the synopsis in 29.3.3 [atomics.types.generic]: |
| </p> |
| |
| <blockquote><pre>template <class T> struct atomic<T*> : atomic_address { |
| <ins>void store(T*, memory_order = memory_order_seq_cst) volatile;</ins> |
| <ins>T* load( memory_order = memory_order_seq_cst ) volatile;</ins> |
| <ins>T* swap( T*, memory_order = memory_order_seq_cst ) volatile;</ins> |
| <ins>bool compare_swap( T*&, T*, memory_order, memory_order ) volatile;</ins> |
| <ins>bool compare_swap( T*&, T*, memory_order = memory_order_seq_cst ) volatile;</ins> |
| |
| T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; |
| T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile; |
| |
| atomic() = default; |
| constexpr explicit atomic(T<ins>*</ins>); |
| atomic(const atomic&) = delete; |
| atomic& operator=(const atomic&) = delete; |
| |
| T* operator=(T*) volatile; |
| T* operator++(int) volatile; |
| T* operator--(int) volatile; |
| T* operator++() volatile; |
| T* operator--() volatile; |
| T* operator+=(ptrdiff_t) volatile; |
| T* operator-=(ptrdiff_t) volatile; |
| }; |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="770"></a>770. std::function should use rvalue swap</h3> |
| <p><b>Section:</b> 20.6.15 [func.wrap] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2008-01-10</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| It is expected that typical implementations of <tt>std::function</tt> will |
| use dynamic memory allocations at least under given conditions, |
| so it seems appropriate to change the current lvalue swappabilty of |
| this class to rvalue swappability. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 20.6 [function.objects], header <tt><functional></tt> synopsis, just below of |
| </p> |
| |
| <blockquote><pre>template<class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&); |
| <ins>template<class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&&, function<R(ArgTypes...)>&); |
| template<class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&&);</ins> |
| </pre></blockquote> |
| |
| <p> |
| In 20.6.15.2 [func.wrap.func] class <tt>function</tt> definition, change |
| </p> |
| |
| <blockquote><pre>void swap(function&<ins>&</ins>); |
| </pre></blockquote> |
| |
| <p> |
| In 20.6.15.2 [func.wrap.func], just below of |
| </p> |
| |
| <blockquote><pre>template <class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&); |
| <ins>template <class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&&, function<R(ArgTypes...)>&); |
| template <class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&&);</ins> |
| </pre></blockquote> |
| |
| <p> |
| In 20.6.15.2.2 [func.wrap.func.mod] change |
| </p> |
| |
| <blockquote><pre>void swap(function&<ins>&</ins> other); |
| </pre></blockquote> |
| |
| <p> |
| In 20.6.15.2.7 [func.wrap.func.alg] add the two overloads |
| </p> |
| |
| <blockquote><pre><ins>template<class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>&& f1, function<R(ArgTypes...)>& f2); |
| template<class R, class... ArgTypes> |
| void swap(function<R(ArgTypes...)>& f1, function<R(ArgTypes...)>&& f2);</ins> |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="775"></a>775. Tuple indexing should be unsigned?</h3> |
| <p><b>Section:</b> 20.4.1.4 [tuple.helper] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Alisdair Meredith <b>Date:</b> 2008-01-16</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The tuple element access API identifies the element in the sequence |
| using signed integers, and then goes on to enforce the requirement that |
| I be >= 0. There is a much easier way to do this - declare I as |
| <tt>unsigned</tt>. |
| </p> |
| <p> |
| In fact the proposal is to use <code>std::size_t</code>, matching the type used in the <tt>tuple_size</tt> API. |
| </p> |
| <p> |
| A second suggestion is that it is hard to imagine an API that deduces |
| and index at compile time and returns a reference throwing an exception. |
| Add a specific <em>Throws:</em> Nothing paragraph to each element |
| access API. |
| </p> |
| <p> |
| In addition to <code>tuple</code>, update the API applies to |
| <code>pair</code> and <code>array</code>, and should be updated |
| accordingly. |
| </p> |
| |
| <p> |
| A third observation is that the return type of the <code>get</code> |
| functions for <code>std::pair</code> is pseudo-code, but it is not |
| clearly marked as such. There is actually no need for pseudo-code as |
| the return type can be specified precisely with a call to |
| <code>tuple_element</code>. This is already done for |
| <code>std::tuple</code>, and <code>std::array</code> does not have a |
| problem as all elements are of type <code>T</code>. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Update header <utility> synopsis in 20.2 [utility] |
| </p> |
| <pre><em>// 20.2.3, tuple-like access to pair:</em> |
| template <class T> class tuple_size; |
| template <<del>int</del><ins>size_t</ins> I, class T> class tuple_element; |
| |
| template <class T1, class T2> struct tuple_size<std::pair<T1, T2> >; |
| template <class T1, class T2> struct tuple_element<0, std::pair<T1, T2> >; |
| template <class T1, class T2> struct tuple_element<1, std::pair<T1, T2> >; |
| |
| template<<del>int</del><ins>size_t</ins> I, class T1, class T2> |
| <del>P</del><ins>typename tuple_element<I, std::pair<T1, T2> >::type </ins>& get(std::pair<T1, T2>&); |
| template<<del>int</del><ins>size_t</ins> I, class T1, class T2> |
| const <del>P</del><ins>typename tuple_element<I, std::pair<T1, T2> >::type </ins>& get(const std::pair<T1, T2>&); |
| </pre> |
| <p> |
| Update <strong>20.2.3 [pairs] Pairs</strong> |
| </p> |
| <pre>template<<del>int</del><ins>size_t</ins> I, class T1, class T2> |
| <del>P</del><ins>typename tuple_element<I, std::pair<T1, T2> >::type </ins>& get(pair<T1, T2>&); |
| template<<del>int</del><ins>size_t</ins> I, class T1, class T2> |
| const <del>P</del><ins>typename tuple_element<I, std::pair<T1, T2> >::type </ins>& get(const pair<T1, T2>&); |
| </pre> |
| <p> |
| <del>24 <em>Return type:</em> If <code>I == 0</code> then <code>P</code> is <code>T1</code>, if <code>I == 1</code> then <code>P</code> is <code>T2</code>, and otherwise the program is ill-formed.</del> |
| </p> |
| <p> |
| 25 <em>Returns:</em> If <code>I == 0</code> returns <code>p.first</code>, <del>otherwise</del> <ins>if <code>I == 1</code></ins> returns <code>p.second</code><ins>, and otherwise the program is ill-formed</ins>. |
| </p> |
| <p> |
| <ins><em>Throws:</em> Nothing.</ins> |
| </p> |
| |
| |
| <p> |
| Update header <tuple> synopsis in 20.4 [tuple] with a APIs as below: |
| </p> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class T> class tuple_element; <em>// undefined</em> |
| template <<del>int</del><ins>size_t</ins> I, class... Types> class tuple_element<I, tuple<Types...> >; |
| |
| <em>// 20.3.1.4, element access:</em> |
| template <<del>int</del><ins>size_t</ins> I, class... Types> |
| typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>&); |
| template <<del>int</del><ins>size_t</ins> I, class ... types> |
| typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>&); |
| </pre> |
| |
| <p> |
| Update <strong>20.4.1.4 [tuple.helper] Tuple helper classes</strong> |
| </p> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class... Types> |
| class tuple_element<I, tuple<Types...> > { |
| public: |
| typedef TI type; |
| };</pre> |
| <p> |
| 1 <em>Requires:</em> <code><del>0 <= I and </del>I < sizeof...(Types)</code>. The program is ill-formed if <code>I</code> is out of bounds. |
| </p> |
| <p> |
| 2 <em>Type:</em> <code>TI</code> is the type of the <code>I</code>th element of <code>Types</code>, where indexing is zero-based. |
| </p> |
| <p> |
| Update <strong>20.4.1.5 [tuple.elem] Element access</strong> |
| </p> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class... types > |
| typename tuple_element<I, tuple<Types...> >::type& get(tuple<Types...>& t); |
| </pre> |
| 1 <em>Requires:</em> <code><del>0 <= I and </del>I < sizeof...(Types)</code>. The program is ill-formed if <code>I</code> is out of bounds. |
| <p> |
| 2 <em>Returns:</em> A reference to the <code>I</code>th element of <code>t</code>, where indexing is zero-based. |
| </p> |
| <ins><em>Throws:</em> Nothing.</ins> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class... types> |
| typename tuple_element<I, tuple<Types...> >::type const& get(const tuple<Types...>& t); |
| </pre> |
| <p> |
| 3 <em>Requires:</em> <code><del>0 <= I and </del>I < sizeof...(Types)</code>. The program is ill-formed if <code>I</code> is out of bounds. |
| </p> |
| <p> |
| 4 <em>Returns:</em> A const reference to the <code>I</code>th element of <code>t</code>, where indexing is zero-based. |
| </p> |
| <p> |
| <ins><em>Throws:</em> Nothing.</ins> |
| </p> |
| |
| |
| <p> |
| Update header <array> synopsis in 20.2 [utility] |
| </p> |
| <pre>template <class T> class tuple_size; <em>// forward declaration</em> |
| template <<del>int</del><ins>size_t</ins> I, class T> class tuple_element; <em>// forward declaration</em> |
| template <class T, size_t N> |
| struct tuple_size<array<T, N> >; |
| template <<del>int</del><ins>size_t</ins> I, class T, size_t N> |
| struct tuple_element<I, array<T, N> >; |
| template <<del>int</del><ins>size_t</ins> I, class T, size_t N> |
| T& get(array<T, N>&); |
| template <<del>int</del><ins>size_t</ins> I, class T, size_t N> |
| const T& get(const array<T, N>&); |
| </pre> |
| |
| <p> |
| Update <strong>23.2.1.6 [array.tuple] Tuple interface to class template array</strong> |
| </p> |
| <pre>tuple_element<<ins>size_t </ins>I, array<T, N> >::type |
| </pre> |
| <p> |
| 3 <em>Requires:</em> <code><del>0 <= </del>I < N.</code> The program is ill-formed if <code>I</code> is out of bounds. |
| </p> |
| <p> |
| 4 <em>Value:</em> The type <code>T</code>. |
| </p> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class T, size_t N> T& get(array<T, N>& a); |
| </pre> |
| <p> |
| 5 <em>Requires:</em> <code><del>0 <= </del>I < N</code>. The program is ill-formed if <code>I</code> is out of bounds. |
| </p> |
| <p> |
| <em>Returns:</em> A reference to the <code>I</code>th element of <code>a</code>, where indexing is zero-based. |
| </p> |
| <p> |
| <ins><em>Throws:</em> Nothing.</ins> |
| </p> |
| <pre>template <<del>int</del><ins>size_t</ins> I, class T, size_t N> const T& get(const array<T, N>& a); |
| </pre> |
| <p> |
| 6 <em>Requires:</em> <code><del>0 <= </del>I < N</code>. The program is ill-formed if <code>I</code> is out of bounds. |
| </p> |
| <p> |
| 7 <em>Returns:</em> A const reference to the <code>I</code>th element of <code>a</code>, where indexing is zero-based. |
| </p> |
| <p> |
| <ins><em>Throws:</em> Nothing.</ins> |
| </p> |
| |
| |
| <p><i>[ |
| Bellevue: Note also that the phrase "The program is ill-formed if I is |
| out of bounds" in the requires clauses are probably unnecessary, and |
| could be removed at the editor's discretion. Also std:: qualification |
| for pair is also unnecessary. |
| ]</i></p> |
| |
| |
| |
| |
| <hr> |
| <h3><a name="777"></a>777. Atomics Library Issue</h3> |
| <p><b>Section:</b> 29.4 [atomics.types.operations] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Lawrence Crowl <b>Date:</b> 2008-01-21</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#atomics.types.operations">issues</a> in [atomics.types.operations].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The load functions are defined as |
| </p> |
| |
| <blockquote><pre>C atomic_load(volatile A* object); |
| C atomic_load_explicit(volatile A* object, memory_order); |
| C A::load(memory_order order = memory_order_seq_cst) volatile; |
| </pre></blockquote> |
| |
| <p> |
| which prevents their use in <tt>const</tt> contexts. |
| </p> |
| |
| <p><i>[ |
| post Bellevue Peter adds: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#777">777</a> suggests making <tt>atomic_load</tt> operate on <tt>const</tt> objects. There is a |
| subtle point here. Atomic loads do not generally write to the object, except |
| potentially for the <tt>memory_order_seq_cst</tt> constraint. Depending on the |
| architecture, a dummy write with the same value may be required to be issued |
| by the atomic load to maintain sequential consistency. This, in turn, may |
| make the following code: |
| </p> |
| |
| <blockquote><pre>const atomic_int x{}; |
| |
| int main() |
| { |
| x.load(); |
| } |
| </pre></blockquote> |
| |
| <p> |
| dump core under a straightforward implementation that puts const objects in |
| a read-only section. |
| </p> |
| <p> |
| There are ways to sidestep the problem, but it needs to be considered. |
| </p> |
| <p> |
| The tradeoff is between making the data member of the atomic types |
| mutable and requiring the user to explicitly mark atomic members as |
| mutable, as is already the case with mutexes. |
| </p> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add the <tt>const</tt> qualifier to <tt>*object</tt> and <tt>*this</tt>. |
| </p> |
| |
| <blockquote><pre>C atomic_load(<ins>const</ins> volatile A* object); |
| C atomic_load_explicit(<ins>const</ins> volatile A* object, memory_order); |
| C A::load(memory_order order = memory_order_seq_cst) <ins>const</ins> volatile; |
| </pre></blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="778"></a>778. std::bitset does not have any constructor taking a string literal</h3> |
| <p><b>Section:</b> 23.3.5.1 [bitset.cons] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Thorsten Ottosen <b>Date:</b> 2008-01-24</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#bitset.cons">issues</a> in [bitset.cons].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Duplicate of:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#116">116</a></p> |
| <p><b>Discussion:</b></p> |
| <p> |
| A small issue with <tt>std::bitset</tt>: it does not have any constructor |
| taking a string literal, which is clumsy and looks like an oversigt when |
| we tried to enable uniform use of <tt>string</tt> and <tt>const char*</tt> in the library. |
| </p> |
| |
| <p> |
| Suggestion: Add |
| </p> |
| |
| <blockquote><pre>explicit bitset( const char* str ); |
| </pre></blockquote> |
| |
| <p> |
| to std::bitset. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add to synopsis in 23.3.5 [template.bitset] |
| </p> |
| |
| <blockquote><pre>explicit bitset( const char* str ); |
| </pre></blockquote> |
| |
| <p> |
| Add to synopsis in 23.3.5.1 [bitset.cons] |
| </p> |
| |
| <blockquote><pre>explicit bitset( const char* str ); |
| </pre> |
| <p> |
| <i>Effects:</i> Constructs a <tt>bitset</tt> as if <tt>bitset(string(str))</tt>. |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="781"></a>781. <tt>std::complex</tt> should add missing C99 functions</h3> |
| <p><b>Section:</b> 26.3.7 [complex.value.ops] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2008-01-26</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#complex.value.ops">issues</a> in [complex.value.ops].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| A comparision of the N2461 header <tt><complex></tt> synopsis ([complex.synopsis]) |
| with the C99 standard (ISO 9899, 2nd edition and the two corrigenda) show |
| some complex functions that are missing in C++. These are: |
| </p> |
| |
| <ol> |
| <li> |
| 7.3.9.4: (required elements of the C99 library)<br> |
| The <tt>cproj</tt> functions |
| </li> |
| <li> |
| 7.26.1: (optional elements of the C99 library)<br> |
| <pre>cerf cerfc cexp2 |
| cexpm1 clog10 clog1p |
| clog2 clgamma ctgamma |
| </pre> |
| </li> |
| </ol> |
| |
| <p> |
| I propose that at least the required <tt>cproj</tt> overloads are provided as equivalent |
| C++ functions. This addition is easy to do in one sentence (delegation to C99 |
| function). |
| </p> |
| |
| <p> |
| Please note also that the current entry <tt>polar</tt> |
| in 26.3.9 [cmplx.over]/1 |
| should be removed from the mentioned overload list. It does not make sense to require that a |
| function already expecting <em>scalar</em> arguments |
| should cast these arguments into corresponding |
| <tt>complex<T></tt> arguments, which are not accepted by |
| this function. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| In 26.3.1 [complex.synopsis] add just between the declaration of <tt>conj</tt> and <tt>fabs</tt>: |
| </p> |
| |
| <blockquote><pre>template<class T> complex<T> conj(const complex<T>&); |
| <ins>template<class T> complex<T> proj(const complex<T>&);</ins> |
| template<class T> complex<T> fabs(const complex<T>&); |
| </pre></blockquote> |
| |
| <p> |
| In 26.3.7 [complex.value.ops] just after p.6 (return clause of <tt>conj</tt>) add: |
| </p> |
| |
| <blockquote> |
| <pre>template<class T> complex<T> proj(const complex<T>& x); |
| </pre> |
| <blockquote> |
| |
| <i>Effects:</i> Behaves the same as C99 function <tt>cproj</tt>, defined in |
| subclause 7.3.9.4." |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| In 26.3.9 [cmplx.over]/1, add one further entry <tt>proj</tt> to |
| the overload list. |
| </p> |
| |
| <blockquote> |
| <p> |
| The following function templates shall have additional overloads: |
| </p> |
| <blockquote><pre>arg norm |
| conj <del>polar</del> <ins>proj</ins> |
| imag real |
| </pre></blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="782"></a>782. Extended <tt>seed_seq</tt> constructor is useless</h3> |
| <p><b>Section:</b> 26.4.7.1 [rand.util.seedseq] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2008-01-27</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.util.seedseq">active issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.util.seedseq">issues</a> in [rand.util.seedseq].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| Part of the resolution of n2423, issue 8 was the proposal to |
| extend the <tt>seed_seq</tt> constructor accepting an input range |
| as follows (which is now part of N2461): |
| </p> |
| |
| <blockquote><pre>template<class InputIterator, |
| size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits> |
| seed_seq(InputIterator begin, InputIterator end); |
| </pre></blockquote> |
| |
| <p> |
| First, the expression <tt>iterator_traits<InputIterator>::value_type</tt> |
| is invalid due to missing <tt>typename</tt> keyword, which is easy to |
| fix. |
| </p> |
| |
| <p> |
| Second (and worse), while the language now supports default |
| template arguments of function templates, this customization |
| point via the second <tt>size_t</tt> template parameter is of no advantage, |
| because <tt>u</tt> can never be deduced, and worse - because it is a |
| constructor function template - it can also never be explicitly |
| provided (14.8.1 [temp.arg.explicit]/7). |
| </p> |
| |
| <p> |
| The question arises, which advantages result from a compile-time |
| knowledge of <tt>u</tt> versus a run time knowledge? If run time knowledge |
| suffices, this parameter should be provided as normal function |
| default argument [Resolution marked (A)], if compile-time knowledge |
| is important, this could be done via a tagging template or more |
| user-friendly via a standardized helper generator function |
| (<tt>make_seed_seq</tt>), which allows this [Resolution marked (B)]. |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| Fermilab does not have a strong opinion. Would prefer to go with |
| solution A. Bill agrees that solution A is a lot simpler and does the |
| job. |
| </p> |
| <p> |
| Proposed Resolution: Accept Solution A. |
| </p> |
| </blockquote> |
| |
| <p> |
| Issue <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#803">803</a> claims to make this issue moot. |
| </p> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <ol type="A"> |
| <li> |
| <p> |
| In 26.4.7.1 [rand.util.seedseq]/2, class <tt>seed_seq</tt> synopsis replace: |
| </p> |
| |
| <blockquote><pre>class seed_seq |
| { |
| public: |
| ... |
| template<class InputIterator<del>, |
| size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits</del>> |
| seed_seq(InputIterator begin, InputIterator end<ins>, |
| size_t u = numeric_limits<typename iterator_traits<InputIterator>::value_type>::digits</ins>); |
| ... |
| }; |
| </pre></blockquote> |
| |
| <p> |
| and do a similar replacement in the member description between |
| p.3 and p.4. |
| </p> |
| </li> |
| |
| <li> |
| <p> |
| In 26.4.7.1 [rand.util.seedseq]/2, class <tt>seed_seq</tt> synopsis <em>and</em> in the |
| member description between p.3 and p.4 replace: |
| </p> |
| |
| <blockquote><pre>template<class InputIterator<del>, |
| size_t u = numeric_limits<iterator_traits<InputIterator>::value_type>::digits</del>> |
| seed_seq(InputIterator begin, InputIterator end); |
| <ins>template<class InputIterator, size_t u> |
| seed_seq(InputIterator begin, InputIterator end, <i>implementation-defined</i> s);</ins> |
| </pre></blockquote> |
| |
| <p> |
| In 26.4.2 [rand.synopsis], header <tt><random></tt> synopsis, immediately after the |
| class <tt>seed_seq</tt> declaration <em>and</em> in 26.4.7.1 [rand.util.seedseq]/2, immediately |
| after the class <tt>seed_seq</tt> definition add: |
| </p> |
| |
| <blockquote><pre>template<size_t u, class InputIterator> |
| seed_seq make_seed_seq(InputIterator begin, InputIterator end); |
| </pre></blockquote> |
| |
| <p> |
| In 26.4.7.1 [rand.util.seedseq], just before p.5 insert two paragraphs: |
| </p> |
| |
| <blockquote> |
| <p> |
| The first constructor behaves as if it would provide an |
| integral constant expression <tt>u</tt> of type <tt>size_t</tt> of value |
| <tt>numeric_limits<typename iterator_traits<InputIterator>::value_type>::digits</tt>. |
| </p> |
| <p> |
| The second constructor uses an implementation-defined mechanism |
| to provide an integral constant expression <tt>u</tt> of type <tt>size_t</tt> and |
| is called by the function <tt>make_seed_seq</tt>. |
| </p> |
| </blockquote> |
| |
| <p> |
| In 26.4.7.1 [rand.util.seedseq], just after the last paragraph add: |
| </p> |
| |
| <blockquote> |
| <pre>template<size_t u, class InputIterator> |
| seed_seq make_seed_seq(InputIterator begin, InputIterator end); |
| </pre> |
| <blockquote> |
| <p> |
| where <tt>u</tt> is used to construct an object <tt>s</tt> of implementation-defined type. |
| </p> |
| <p> |
| <i>Returns:</i> <tt>seed_seq(begin, end, s)</tt>; |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| </li> |
| </ol> |
| |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="783"></a>783. <tt>thread::id</tt> reuse</h3> |
| <p><b>Section:</b> 30.2.1.1 [thread.thread.id] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Hans Boehm <b>Date:</b> 2008-02-01</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| The current working paper |
| (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2497.html">N2497</a>, |
| integrated just before Bellevue) is |
| not completely clear whether a given <tt>thread::id</tt> value may be reused once |
| a thread has exited and has been joined or detached. Posix allows |
| thread ids (<tt>pthread_t</tt> values) to be reused in this case. Although it is |
| not completely clear whether this originally was the right decision, it |
| is clearly the established practice, and we believe it was always the |
| intent of the C++ threads API to follow Posix and allow this. Howard |
| Hinnant's example implementation implicitly relies on allowing reuse |
| of ids, since it uses Posix thread ids directly. |
| </p> |
| |
| <p> |
| It is important to be clear on this point, since it the reuse of thread |
| ids often requires extra care in client code, which would not be |
| necessary if thread ids were unique across all time. For example, a |
| hash table indexed by thread id may have to be careful not to associate |
| data values from an old thread with a new one that happens to reuse the |
| id. Simply removing the old entry after joining a thread may not be |
| sufficient, if it creates a visible window between the join and removal |
| during which a new thread with the same id could have been created and |
| added to the table. |
| </p> |
| |
| <p><i>[ |
| post Bellevue Peter adds: |
| ]</i></p> |
| |
| |
| <blockquote> |
| <p> |
| There is a real issue with <tt>thread::id</tt> reuse, but I urge the LWG to |
| reconsider fixing this by disallowing reuse, rather than explicitly allowing |
| it. Dealing with thread id reuse is an incredibly painful exercise that |
| would just force the world to reimplement a non-conflicting <tt>thread::id</tt> over |
| and over. |
| </p> |
| <p> |
| In addition, it would be nice if a <tt>thread::id</tt> could be manipulated |
| atomically in a lock-free manner, as motivated by the recursive lock |
| example: |
| </p> |
| |
| <p> |
| <a href="http://www.decadentplace.org.uk/pipermail/cpp-threads/2006-August/001091.html">http://www.decadentplace.org.uk/pipermail/cpp-threads/2006-August/001091.html</a> |
| </p> |
| </blockquote> |
| |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Add a sentence to 30.2.1.1 [thread.thread.id]/p1: |
| </p> |
| |
| <blockquote> |
| <p> |
| An object of type <code>thread::id</code> provides |
| a unique identifier for each thread of execution |
| and a single distinct value for all thread objects |
| that do not represent a thread of execution ([thread.threads.class]). |
| Each thread of execution has a <code>thread::id</code> |
| that is not equal to the <code>thread::id</code> |
| of other threads of execution |
| and that is not equal to |
| the <code>thread::id</code> of <code>std::thread</code> objects |
| that do not represent threads of execution. |
| <ins>The library may reuse the value of a <code>thread::id</code> of a |
| terminated thread that can no longer be joined.</ins> |
| </p> |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="789"></a>789. <tt>xor_combine_engine(result_type)</tt> should be explicit</h3> |
| <p><b>Section:</b> 26.4.4.4 [rand.adapt.xor] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger <b>Date:</b> 2008-02-09</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.adapt.xor">issues</a> in [rand.adapt.xor].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>xor_combine_engine(result_type)</tt> should be <tt>explicit</tt>. (Obvious oversight.) |
| </p> |
| |
| <p><i>[ |
| Bellevue: |
| ]</i></p> |
| |
| |
| <blockquote> |
| Non-controversial. Bill is right, but Fermilab believes that this is |
| easy to use badly and hard to use right, and so it should be removed |
| entirely. Got into TR1 by well defined route, do we have permission to |
| remove stuff? Should probably check with Jens, as it is believed he is |
| the originator. Broad consensus that this is not a robust engine |
| adapter. |
| </blockquote> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Remove xor_combine_engine from synopsis of 26.4.2 [rand.synopsis]. |
| </p> |
| <p> |
| Remove 26.4.4.4 [rand.adapt.xor] <tt>xor_combine_engine</tt>. |
| </p> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="792"></a>792. <tt>piecewise_constant_distribution</tt> is undefined for a range with just one endpoint</h3> |
| <p><b>Section:</b> 26.4.8.5.2 [rand.dist.samp.pconst] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> P.J. Plauger <b>Date:</b> 2008-02-09</p> |
| <p><b>View other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index-open.html#rand.dist.samp.pconst">active issues</a> in [rand.dist.samp.pconst].</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#rand.dist.samp.pconst">issues</a> in [rand.dist.samp.pconst].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <tt>piecewise_constant_distribution</tt> is undefined for a range with just one |
| endpoint. (Probably should be the same as an empty range.) |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change 26.4.8.5.2 [rand.dist.samp.pconst] paragraph 3b: |
| </p> |
| |
| <blockquote> |
| b) If <tt>firstB == lastB</tt> <ins>or the sequence <tt>w</tt> has the length zero</ins>, |
| </blockquote> |
| |
| |
| |
| |
| |
| <hr> |
| <h3><a name="798"></a>798. Refactoring of binders lead to interface breakage</h3> |
| <p><b>Section:</b> D.8 [depr.lib.binders] <b>Status:</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#WP">WP</a> |
| <b>Submitter:</b> Daniel Krügler <b>Date:</b> 2008-02-14</p> |
| <p><b>View all other</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-index.html#depr.lib.binders">issues</a> in [depr.lib.binders].</p> |
| <p><b>View all issues with</b> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-status.html#WP">WP</a> status.</p> |
| <p><b>Discussion:</b></p> |
| <p> |
| <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2521.pdf">N2521</a> |
| and its earlier predecessors have moved the old binders from |
| [lib.binders] to D.8 [depr.lib.binders] thereby introducing some renaming |
| of the template parameter names (<tt>Operation -> Fn</tt>). During this |
| renaming process the <em>protected</em> data member <tt>op</tt> was also renamed to |
| <tt>fn</tt>, which seems as an unnecessary interface breakage to me - even if |
| this user access point is probably rarely used. |
| </p> |
| |
| |
| <p><b>Proposed resolution:</b></p> |
| <p> |
| Change D.8.1 [depr.lib.binder.1st]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Fn> |
| class binder1st |
| : public unary_function<typename Fn::second_argument_type, |
| typename Fn::result_type> { |
| protected: |
| Fn <del>fn</del> <ins>op</ins>; |
| typename Fn::first_argument_type value; |
| public: |
| binder1st(const Fn& x, |
| const typename Fn::first_argument_type& y); |
| typename Fn::result_type |
| operator()(const typename Fn::second_argument_type& x) const; |
| typename Fn::result_type |
| operator()(typename Fn::second_argument_type& x) const; |
| }; |
| </pre> |
| |
| <blockquote> |
| <p> |
| -1- The constructor initializes <del><tt>fn</tt></del> <ins><tt>op</tt></ins> with <tt>x</tt> and <tt>value</tt> with <tt>y</tt>. |
| </p> |
| <p> |
| -2- <tt>operator()</tt> returns <tt><del>fn</del><ins>op</ins>(value,x)</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| <p> |
| Change D.8.3 [depr.lib.binder.2nd]: |
| </p> |
| |
| <blockquote> |
| <pre>template <class Fn> |
| class binder2nd |
| : public unary_function<typename Fn::first_argument_type, |
| typename Fn::result_type> { |
| protected: |
| Fn <del>fn</del> <ins>op</ins>; |
| typename Fn::second_argument_type value; |
| public: |
| binder2nd(const Fn& x, |
| const typename Fn::second_argument_type& y); |
| typename Fn::result_type |
| operator()(const typename Fn::first_argument_type& x) const; |
| typename Fn::result_type |
| operator()(typename Fn::first_argument_type& x) const; |
| }; |
| </pre> |
| |
| <blockquote> |
| <p> |
| -1- The constructor initializes <del><tt>fn</tt></del> <ins><tt>op</tt></ins> with <tt>x</tt> and <tt>value</tt> with <tt>y</tt>. |
| </p> |
| <p> |
| -2- <tt>operator()</tt> returns <tt><del>fn</del><ins>op</ins>(value,x)</tt>. |
| </p> |
| </blockquote> |
| </blockquote> |
| |
| |
| |
| |
| |
| |
| </body></html> |