1

I am surprised to see that the standard C++ std::vector::pop_back() mutator is not noexcept, and so is permitted to throw exceptions. Surprised, because it is a destruction type operation, which should never need to allocate any resources.

When it practice could it throw an exception? Is it permitted to throw an exception only to propagate an exception thrown by the destructor of the last element of the vector? So a std::vector holding values of a properly behaved class, which has a noexcept destructor, will not throw exceptions from pop_back()?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Raedwald
  • 46,613
  • 43
  • 151
  • 237

1 Answers1

3

It's not noexcept because it is narrow contract.

If you attempt to pop_back an empty vector, the behavior is undefined, and a debug-mode implementation may well choose to throw an exception.

Destructors invoked by the standard library must not throw, on pain of undefined behavior.

T.C.
  • 133,968
  • 17
  • 288
  • 421
  • 1
    I am not sure I agree. The language isn't concerned with what happens on UB. The standard only defines what happens on defined behavior. On the other hand I see your point. It would be difficult for implementations to throw on UB if they chose do to so. Still my personal feeling is that is not the reason why it's not `noexcept`. – bolov Mar 18 '19 at 13:23
  • 2
    @bolov That an implementation may for one reason or another wish to throw an exception upon a precondition violation is the standard justification for the Lakos rule, all the way back to [N3248](https://wg21.link/N3248), which is the the predecessor to [N3279](https://wg21.link/N3279). – T.C. Mar 19 '19 at 00:13
  • very interesting read, thank you. I stand corrected. – bolov Mar 19 '19 at 00:17