847. string exception safety guarantees

Section: [string.require] Status: C++11 Submitter: Hervé Brönnimann Opened: 2008-06-05 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [string.require].

View all issues with C++11 status.


In March, on comp.lang.c++.moderated, I asked what were the string exception safety guarantees are, because I cannot see *any* in the working paper, and any implementation I know offers the strong exception safety guarantee (string unchanged if a member throws exception). The closest the current draft comes to offering any guarantees is 24.3.2 [basic.string], para 3:

The class template basic_string conforms to the requirements for a Sequence Container (23.1.1), for a Reversible Container (23.1), and for an Allocator-aware container (91). The iterators supported by basic_string are random access iterators (24.1.5).

However, the chapter 23 only says, on the topic of exceptions: 26.2 [container.requirements], para 10:

Unless otherwise specified (see and all container types defined in this clause meet the following additional requirements:

I take it as saying that this paragraph has *no* implication on std::basic_string, as basic_string isn't defined in Clause 23 and this paragraph does not define a *requirement* of Sequence nor Reversible Container, just of the models defined in Clause 23. In addition, LWG Issue 718 proposes to remove 26.2 [container.requirements], para 3.

Finally, the fact that no operation on Traits should throw exceptions has no bearing, except to suggest (since the only other throws should be allocation, out_of_range, or length_error) that the strong exception guarantee can be achieved.

The reaction in that group by Niels Dekker, Martin Sebor, and Bo Persson, was all that this would be worth an LWG issue.

A related issue is that erase() does not throw. This should be stated somewhere (and again, I don't think that the 26.2 [container.requirements], para 1 applies here).

[ San Francisco: ]

Implementors will study this to confirm that it is actually possible.

[ Daniel adds 2009-02-14: ]

The proposed resolution of paper N2815 interacts with this issue (the paper does not refer to this issue).

[ 2009-07 Frankfurt: ]

Move to Ready.

Proposed resolution:

Add a blanket statement in [string.require]:

- if any member function or operator of basic_string<charT, traits, Allocator> throws, that function or operator has no effect.

- no erase() or pop_back() function throws.

As far as I can tell, this is achieved by any implementation. If I made a mistake and it is not possible to offer this guarantee, then either state all the functions for which this is possible (certainly at least operator+=, append, assign, and insert), or add paragraphs to Effects clauses wherever appropriate.