0

Let me quote part of the section in Professional C++ 5th. ed.(Page 237):

Before C++17, you had to use make_unique() ... Consider the following call to a function called foo():

foo(unique_ptr<Simple> { new Simple{} }, unique_ptr<Bar> { new Bar { data() } });

If the constructor of Simple or Bar, or the data() function, throws an exception, depending on your compiler optimizations, it was possible that either a Simple or a Bar object would be leaked. With make_unique(), nothing would leak:

foo(make_unique<Simple>(), make_unique<Bar>(data()))

Since C++17, both calls to foo() are safe, but I still recommend using make_unique() as it results in code that is easier to read.

I know why it's not safe before C++17 since new may happen first and data() may be called then before the new'd result is passed to unique_ptr, so when an exception throws, memory leaks happen. But why does it become safe since C++17?

o_oTurtle
  • 1,091
  • 3
  • 12
  • 3
    They changed the rules, see the papers at the bottom of [this answer](https://stackoverflow.com/a/22571331/4342498) – NathanOliver May 05 '23 at 01:57
  • 2
    TLDR: sequence is changed in C++17, function parameter order evaluation is guaranteed, and each function parameter is guaranteed to be evaluated before the next one. – Sam Varshavchik May 05 '23 at 02:05
  • When you say *`new` may happen first and `data()` may be called then before the `new`'d result is passed to `unique_ptr`, so when an exception throws, memory leaks happen*, you are thinking of the subexpression `unique_ptr{ new Bar { data() } }`. But this is not correct; all versions of C++ handle an exception in this case without leaving a memory leak. The problem before C++17 is that one `new`'d object can be completed, and before being attached to its `unique_ptr`, the other argument expression throws an exception. C++17 forbids this. – j6t May 05 '23 at 06:30
  • 1
    @SamVarshavchik Each is fully evaluated after the next one, but in which order is importantly still indeterminate. – user17732522 May 05 '23 at 06:47

0 Answers0