What are the implications of the voted in C++17 evaluation order guarantees (P0145) on typical C++ code?
What does it change about things like the following?
In C++14, the following was unsafe:
void foo(std::unique_ptr, std::unique_ptr);
foo(std::unique_ptr(new A), std::unique_ptr(new B));
There are four operations that happen here during the function call
The ordering of these was completely unspecified, and so a perfectly valid ordering is (1), (3), (2), (4). If this ordering was selected and (3) throws, then the memory from (1) leaks - we haven't run (2) yet, which would've prevented the leak.
In C++17, the new rules prohibit interleaving. From [intro.execution]:
For each function invocation F, for every evaluation A that occurs within F and every evaluation B that does not occur within F but is evaluated on the same thread and as part of the same signal handler (if any), either A is sequenced before B or B is sequenced before A.
There is a footnote to that sentence which reads:
In other words, function executions do not interleave with each other.
This leaves us with two valid orderings: (1), (2), (3), (4) or (3), (4), (1), (2). It is unspecified which ordering is taken, but both of these are safe. All the orderings where (1) (3) both happen before (2) and (4) are now prohibited.