Boost C++ Libraries: Ticket #8966: No exception thrown (e.g. std::bad_alloc) on allocation failure in lexical_cast https://svn.boost.org/trac10/ticket/8966 <p> It would be nice, if lexical_cast would throw a different exception from bad_lexical_cast, if an allocation failure occurs. For example by setting stream.exceptions(std::ios::badbit); in line 1999 (it would then throw std::bad_alloc). </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/8966 Trac 1.4.3 Antony Polukhin Tue, 06 Aug 2013 14:13:06 GMT <link>https://svn.boost.org/trac10/ticket/8966#comment:1 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8966#comment:1</guid> <description> <p> This is a very doubtful and unportable feature. According to C++11, setting <code>stream.exceptions(std::ios::badbit);</code> guarantees only that it throws <code>basic_ios::failure</code> in case of <code>badbit</code> error: </p> <p> --- </p> <p> <code>void clear(iostate state = goodbit);</code> </p> <p> Effects: If <code>((state | (rdbuf() ? goodbit : badbit)) &amp; exceptions()) == 0</code>, returns. Otherwise, the function throws an object fail of class <code>basic_ios::failure</code> (27.5.3.1.1), constructed with implementation-defined argument values. </p> <p> <code>void setstate(iostate state);</code> </p> <p> Effects: Calls <code>clear(rdstate() | state)</code> (which may throw basic_ios::failure (27.5.3.1.1)). </p> <p> --- </p> <p> Applying fix from this ticket will break user code (users expecting and catching <code>bad_lexical_cast</code> exceptions) and result in less predictable behaviour. </p> </description> <category>Ticket</category> </item> <item> <author>Martin <martin.raiber@…></author> <pubDate>Tue, 06 Aug 2013 15:29:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8966#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8966#comment:2</guid> <description> <p> True. </p> <p> To add arguments to the other side: </p> <ol><li>Allocation failure is something completely different from a bad_lexical_cast and one would probably want to handle them differently. For example we have code which returns a standard value if the input is not numeric. On allocation failure it should not continue processing, but stop with an error. </li><li>std::bad_alloc is thrown by most of the STL and new and is therefore the standard way to inform callers of allocation failures. That the streams do not throw exceptions can fortunately be changed. Personally, if I did not know about the unusual behavior of streams with regard to exceptions, I would have expected lexical_cast to throw bad_alloc. </li><li>I looked at the MSVCRT and libc++ and both have a catch-all which either sets the bad-bit or rethrows the exception. </li></ol><p> That said. This is clearly cosmetic, because allocation failures are hard to produce on modern overcomitting operating systems. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Tue, 06 Aug 2013 16:27:53 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8966#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8966#comment:3</guid> <description> <p> I'd love to apply that change if it does not break user code. I do not argue that it is better to throw <code>std::bad_alloc</code> than <code>bad_lexical_cast</code> in case of memory error. But the part that breaks user code is <code>basic_ios::failure</code> exceptions. There is a big chance that instead of <code>bad_lexical_cast</code> user will get <code>basic_ios::failure</code> and won't catch it. </p> <p> But a trivial thought popped in my head: "Do catch the <code>basic_ios::failure</code> exceptions and convert them to the <code>bad_lexical_cast</code> exceptions!". I'll look through the tests and if after setting <code>stream.exceptions(std::ios::badbit);</code> the <code>basic_ios::failure</code> exceptions are rare, then I'll apply the patch. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Wed, 07 Aug 2013 11:08:03 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8966#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8966#comment:4</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/85232" title="Do not treat critcal errors as bad_lexical_cast exceptions, but if ...">[85232]</a>) Do not treat critcal errors as bad_lexical_cast exceptions, but if exceptions are on throw correct exception instead (refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8966" title="#8966: Bugs: No exception thrown (e.g. std::bad_alloc) on allocation failure in ... (closed: fixed)">#8966</a>) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Tue, 13 Aug 2013 13:08:39 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/8966#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/8966#comment:5</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/85331" title="Merge from trunk: * Do not treat critcal errors as bad_lexical_cast ...">[85331]</a>) Merge from trunk: </p> <ul><li>Do not treat critcal errors as bad_lexical_cast exceptions, but if exceptions are on, throw correct exception instead (refs <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/8966" title="#8966: Bugs: No exception thrown (e.g. std::bad_alloc) on allocation failure in ... (closed: fixed)">#8966</a>) </li></ul> </description> <category>Ticket</category> </item> <item> <dc:creator>Antony Polukhin</dc:creator> <pubDate>Tue, 13 Aug 2013 13:10:06 GMT</pubDate> <title>status, milestone changed; resolution set https://svn.boost.org/trac10/ticket/8966#comment:6 https://svn.boost.org/trac10/ticket/8966#comment:6 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">fixed</span> </li> <li><strong>milestone</strong> <span class="trac-field-old">To Be Determined</span> → <span class="trac-field-new">Boost 1.55.0</span> </li> </ul> Ticket