Are allocator construct and destroy member functions allowed to throw exceptions from internal logic?

Viewed 130

I'm writing my own container that requires nothrow movable and copyable types. I thought I could simplify logic a bit when it comes to exception safety. But I noticed that construct and destroy member functions of allocators have no wording about when they can and can't throw exceptions.

I'm pretty sure I've read the wording before. Otherwise, even if my type is nothrow movable, construct can still throw an exception from user-provided allocator when, say, I resize the buffer to increase capacity. This requires complex rollback code to guarantee strong exception safety that I really wanted to skip.

Is there a wording that allows to only throw exceptions from calling ctor/dtor or are allocators always require complex machinery to maintain exception safety?

1 Answers

The allocator members can throw. If the standard doesn't say they can't throw, then they can throw.

But in practice, why would they?

Especially for std::allocator::construct and std::allocator::destroy, which do nothing more than just invoke a constructor or destructor. But you should be using std::allocator_traits<Alloc>::construct and std::allocator_traits<Alloc>::destroy anyway, and those do nothing more than call Alloc::construct / Alloc::destroy if that exists, and invoke a constructor/destructor otherwise.

In theory, a pathological allocator could throw in those members, but you should assume they don't. You can't defend against pathologically stupid types.

Related