consider code snippet:
std::shared_ptr<...> p = ...; p->f(std::move(p));
according cppref, operator ->
, ()
of same precedence , both left-to-right associative. presume p->
evaluated before std::move()
, , snippet should fine. vc15 opposite , crashes program. vc15 bug or have got wrong here?
you're invoking undefined behaviour, because order of evaluation of arguments in function call not specified standard, , with...
p->f(std::move(p));
you have two arguments being passed. first of all, this
, , secondly, std::move(p)
. now, there's not-so-obvious problem. you're both reading and writing same shared pointer. can lead anything, otherwise known undefined behaviour. let's not mention you're using std::move()
on such pointer...
*this
pointing *p
, first (explicit) argument holds pointer itself, *p
not valid! let's suppose didn't crashed program (somehow...). then, can lead object being destroyed f
left. but... when shared pointer (assuming single reference left) , object destroyed, function has not still left. again, problems...
that example, , have happened in middle of anything. don't read and write in same expression , you'll okay :).
btw: we know vs standards-complaint, anyway, has nothing order , precedence of operator resolution.
edit: okay if f()
takes universal reference (a.k.a: forwarding reference, a.k.a collapsed-rvalue-reference-black-magic-that-somehow-got-into-the-standard) or rvalue reference. so, example...
void f(std::shared_pointer<...> &&ptr)
everything go beatiful , perfect, as long don't bad things ptr
...
but, if f
takes object of type std::remove_reference_t<decltype(*p)>>
, shared pointer moved on argument , above stuff happens.
Comments
Post a Comment