Suppose I have the following:
#include <memory>
struct A { int x; };
class B {
B(int x, std::unique_ptr<A> a);
};
class C : public B {
C(std::unique_ptr<A> a) : B(a->x, std::move(a)) {}
};
If I understand the C++ rules about "unspecified order of function parameters" correctly, this code is unsafe. If the second argument to B
's constructor is constructed first using the move constructor, then a
now contains a nullptr
and the expression a->x
will trigger undefined behavior (likely segfault). If the first argument is constructed first, then everything will work as intended.
If this were a normal function call, we could just create a temporary:
auto x = a->x
B b{x, std::move(a)};
But in the class initialization list we don't have the freedom to create temporary variables.
Suppose I cannot change B
, is there any possible way to accomplish the above? Namely dereferencing and moving a unique_ptr
in the same function call expression without creating a temporary?
What if you could change B
's constructor but not add new methods such as setX(int)
? Would that help?
Thank you
See Question&Answers more detail:os