In comments under another question, it was stated that a common mistake is to:
invoke
std::function
when calling it leads to destruction of object which holds it
While clearly a "dangerous" thing to do that would be avoided in robust code, is it actually wrong? I cannot find any wording in the standard that ensures:
std::function
must not be destroyed by its target callablestd::function
's lifetime must not end during execution of its target callableTo my knowledge, it is legal and well-defined (though in poor taste) to do things like the following:
struct Foo
{
void baz()
{
delete this;
// Just don't use any members after this point
}
};
int main()
{
Foo* foo = new Foo();
foo->baz();
}
This suggests that, in the absence of any overriding restrictions, none of which I can find, the following would also be technically well-defined:
#include <functional>
struct Bar
{
std::function<void()> func;
};
int main()
{
Bar* bar = new Bar();
bar->func = [&]() { delete bar; };
bar->func();
}
Is this not the case? If not, which wording prohibits it?
(For bonus points, it would be interesting if this has changed since previous standards.)
[res.on.objects]/2:
If an object of a standard library type is accessed, and the beginning of the object's lifetime does not happen before the access, or the access does not happen before the end of the object's lifetime, the behavior is undefined unless otherwise specified. [ Note: This applies even to objects such as mutexes intended for thread synchronization. — end note ]
As far as the library is concerned, a member function can access the object until it returns. It follows that destroying the object in the middle of such a call is undefined unless permission is explicitly granted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With