4

Can std::string s; throw under any circumstances? Is this regulated by the standard (interested in C++03, in case there are differences)?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Irfy
  • 9,323
  • 1
  • 45
  • 67
  • I don't have 03 handy, but in 11, the move constructor is the only one marked `noexcept`. – chris Jan 20 '13 at 02:47
  • I expected move constructors to be `noexcept` in C++11, and copy constructors to be allowed to throw for obvious reasons, but an empty constructor... I'm sure it can be special-cased to not allocate anything, but is it done like that is the question. – Irfy Jan 20 '13 at 02:49

3 Answers3

5

In C++11, the default constructor actually takes one (defaulted) argument, namely the allocator (21.4.2):

explicit basic_string(const Allocator& a = Allocator());

This constructor is not declared as noexcept. (I suppose that would require the allocator to have a non-throwing copy constructor.) As Jonathan and Bo point out, the allocator's copy constructor must not throw any exceptions, but the string's constructor is allowed to perform throwing operations (e.g. allocate an initial piece of memory). It should certainly be possible to write a string-like class that as a no-throw­ing, constexpr constructor, but the standard library string is not specified to be like that.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 2
    The Allocator requirements say the allocator's copy constructor "shall not exit via an exception" and `std::allocator`'s copy ctor is `noexcept` – Jonathan Wakely Jan 20 '13 at 02:56
  • Hmmm. I followed what gets called during default construction and it turns out, the allocator's construction is `throw()`, and the rest `basic_string()` does is only to reinterpret a statically allocated array as an empty string. Only this reinterpretation part is not marked `throw()`, and everything else is. Can a `reinterpret_cast` throw? – Irfy Jan 20 '13 at 05:21
  • 2
    The string constructor is allowed to allocate dynamic memory for the string. That could cause a `bad_alloc`. Most implementations don't, but you cannot formally rely on that. – Bo Persson Jan 20 '13 at 11:02
4

This was changed by WG21/N4002. The first working paper contains it I see is WG21/N4296: // 21.4.2, construct/copy/destroy: basic_string() noexcept : basic_string(Allocator()) { }

FrankHB
  • 2,297
  • 23
  • 19
-2

Sure if allocation isn't possible for any reason it would throw

dchhetri
  • 6,926
  • 4
  • 43
  • 56