Search code examples
c++c++11unique-ptrexception-safety

Exception safety and make_unique


Just to clarify, using make_unique only adds exception safety when you have multiple allocations in an expression, not just one, correct? For example

void f(T*);

f(new T);

is perfectly exception safe (as far as allocations and stuff), while

void f(T*, T*);

f(new T, new T);

is not, correct?


Solution

  • Not only when you have multiple allocations, but whenever you can throw at different places. Consider this:

    f(make_unique<T>(), function_that_can_throw());
    

    Versus:

    f(unique_ptr<T>(new T), function_that_can_throw());
    

    In the second case, the compiler is allowed to call (in order):

    • new T
    • function_that_can_throw()
    • unique_ptr<T>(...)

    Obviously if function_that_can_throw actually throws then you leak. make_unique prevents this case.

    And of course, a second allocation (as in your question) is just a special case of function_that_can_throw().

    As a general rule of thumb, just use make_unique so that your code is consistent. It is always correct (read: exception-safe) when you need a unique_ptr, and it doesn't have any impact on performance, so there is no reason not to use it (while actually not using it introduces a lot of gotchas).