Modify

Ticket #8966 (closed Bugs: fixed)

Opened 9 months ago

Last modified 8 months ago

No exception thrown (e.g. std::bad_alloc) on allocation failure in lexical_cast

Reported by: Martin <martin.raiber@…> Owned by: apolukhin
Milestone: Boost 1.55.0 Component: lexical_cast
Version: Boost Development Trunk Severity: Cosmetic
Keywords: Cc:

Description

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).

Attachments

Change History

comment:1 Changed 9 months ago by apolukhin

This is a very doubtful and unportable feature. According to C++11, setting stream.exceptions(std::ios::badbit); guarantees only that it throws basic_ios::failure in case of badbit error:

---

void clear(iostate state = goodbit);

Effects: If ((state | (rdbuf() ? goodbit : badbit)) & exceptions()) == 0, returns. Otherwise, the function throws an object fail of class basic_ios::failure (27.5.3.1.1), constructed with implementation-defined argument values.

void setstate(iostate state);

Effects: Calls clear(rdstate() | state) (which may throw basic_ios::failure (27.5.3.1.1)).

---

Applying fix from this ticket will break user code (users expecting and catching bad_lexical_cast exceptions) and result in less predictable behaviour.

comment:2 Changed 9 months ago by Martin <martin.raiber@…>

True.

To add arguments to the other side:

  1. 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.
  2. 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.
  3. I looked at the MSVCRT and libc++ and both have a catch-all which either sets the bad-bit or rethrows the exception.

That said. This is clearly cosmetic, because allocation failures are hard to produce on modern overcomitting operating systems.

comment:3 Changed 9 months ago by apolukhin

I'd love to apply that change if it does not break user code. I do not argue that it is better to throw std::bad_alloc than bad_lexical_cast in case of memory error. But the part that breaks user code is basic_ios::failure exceptions. There is a big chance that instead of bad_lexical_cast user will get basic_ios::failure and won't catch it.

But a trivial thought popped in my head: "Do catch the basic_ios::failure exceptions and convert them to the bad_lexical_cast exceptions!". I'll look through the tests and if after setting stream.exceptions(std::ios::badbit); the basic_ios::failure exceptions are rare, then I'll apply the patch.

comment:4 Changed 9 months ago by apolukhin

(In [85232]) Do not treat critcal errors as bad_lexical_cast exceptions, but if exceptions are on throw correct exception instead (refs #8966)

comment:5 Changed 8 months ago by apolukhin

(In [85331]) Merge from trunk:

  • Do not treat critcal errors as bad_lexical_cast exceptions, but if exceptions are on, throw correct exception instead (refs #8966)

comment:6 Changed 8 months ago by apolukhin

  • Status changed from new to closed
  • Resolution set to fixed
  • Milestone changed from To Be Determined to Boost 1.55.0
View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.