We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors step 3 of 4
The promise the standard library reads
void step() noexcept;
noexcept says: nothing thrown from inside this function will escape it. It
is not a request and it is not checked at compile time. If an exception does
try to leave, the program calls std::terminate — no unwinding, no
destructors, no handler anywhere up the stack gets a chance.
That is deliberately brutal, because the promise is not for you. It is for the code that reads it.
What reads it
std::vector needs to relocate its elements when it grows past capacity, and
it wants to keep its strong guarantee: if anything throws during the
growth, the vector is left exactly as it was.
Moving the elements makes that impossible. Halfway through, the old block holds moved-from husks and the new block is half-built; if the next move throws, there is nothing to roll back to, because the originals are gone.
Copying the elements makes it easy. The originals are untouched until every copy has succeeded.
So the vector asks the type:
| Move constructor |
What vector does when it grows |
|---|---|
noexcept |
moves each element |
not noexcept |
copies each element |
A missing keyword turns every reallocation of every vector of your type into
a deep copy. Nothing fails, nothing warns, and the profile just looks like
that. This is the single most expensive one-word omission in C++, and
performance-noexcept-move-constructor is in the gate because of it.
Where the promise belongs
| Move constructor / move assignment | yes — the case above |
swap |
yes — everything that provides a strong guarantee is built on a non-throwing swap |
| Destructors |
already implicitly noexcept; a throw escaping one terminates |
A simple getter, size(), arithmetic |
yes, and it costs nothing |
| Anything that allocates |
no — std::bad_alloc is a thing |
That last row is the discipline. noexcept on a function that pushes onto a
vector is a promise you cannot keep, and the punishment for breaking it is
std::terminate rather than an exception someone could have handled.
When in doubt, leave it off. noexcept is easy to add later and very hard to
remove — it is part of the type of the function, and callers may already be
branching on it.
Your task
grow is given: it appends every buffer to a vector, without reserving, so
the vector reallocates as it goes. Do not change it.
Buffer counts its own copies and moves, and the harness reports both. There
should be no copies at all. Right now there is a copy for every relocation,
and one missing word is the reason.
Stuck?
C++ reference solution
Sign in to attempt this problem and reveal the reference solution.