Opened 9 years ago

Closed 9 years ago

#8966 closed Bugs (fixed)

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

Reported by: Martin <martin.raiber@…> Owned by: Antony Polukhin
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).

Change History (6)

comment:1 by Antony Polukhin, 9 years ago

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 by Martin <martin.raiber@…>, 9 years ago

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 by Antony Polukhin, 9 years ago

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 by Antony Polukhin, 9 years ago

(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 by Antony Polukhin, 9 years ago

(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 by Antony Polukhin, 9 years ago

Milestone: To Be DeterminedBoost 1.55.0
Resolution: fixed
Status: newclosed
Note: See TracTickets for help on using tickets.