(no title)
TwoBit | 4 years ago
I don't see how that is so. C++ 17 allows new Widget to complete and then the priority() call to execute and throw before both are passed to shared_ptr(), thus creating a leak. Your cited example [1] doesn't leak because both arguments are shared_ptr. Seems to me that C++ 17 does indeed solve this latter case but not the former.
dvt|4 years ago
> evaluations of A and B are indeterminately sequenced: they may be performed in any order but may not overlap: either A will be complete before B, or B will be complete before A. The order may be the opposite the next time the same expression is evaluated.
And:
> 21) Every expression in a comma-separated list of expressions in a parenthesized initializer is evaluated as if for a function call (indeterminately-sequenced)
Emphasis mine. What the above basically says is that in the case of some function `f(A, B)`, the arguments `A`, and `B`, are what's known as "indeterminately-sequenced" -- this mean that their execution cannot be interleaved (overlap) -- but they still individually execute in a non-deterministic order (A before B, and sometimes B before A)!
With that said, the good news is that B can now never throw in the middle of A, which is precisely what we have in OP's example.
[1] https://en.cppreference.com/w/cpp/language/eval_order
_huayra_|4 years ago
nyanpasu64|4 years ago
priority() is not passed to shared_ptr(), only to processWidget().
TwoBit|4 years ago
processWidget(new Widget, priority());
I think I saw the above code elsewhere.
ronyclau|4 years ago
However in the Effective C++ example, the `shared_ptr` constructor gave a false sense of security as it seemed the `new`-ed `Widget` was always managed by the smart pointer from its allocation.