When can you delete a standard library object?

82 views
Skip to first unread message

Johannes Schaub

unread,
Apr 11, 2014, 4:52:43 AM4/11/14
to std-dis...@isocpp.org

The question did arise in a Stackoverflow question. Are you allowed to call an std::function which executes a "delete myStdFunctionWrapperPtr;"?

The question is

1. Is it forbidden for a program to do so because otherwise it will be undefined behavior (because it is unspecified what the operator () of std::function does after executing the bound functor).

2. Or is it disallowed for implementations to touch anything of "this" after invocation of the bound functor because it might have deleted "this"?

Ville Voutilainen

unread,
Apr 11, 2014, 5:08:20 AM4/11/14
to std-dis...@isocpp.org
On 11 April 2014 11:52, Johannes Schaub <schaub....@googlemail.com> wrote:
> The question did arise in a Stackoverflow question. Are you allowed to call
> an std::function which executes a "delete myStdFunctionWrapperPtr;"?

And this wrapper destroys the std::function you just called?

>
> The question is
>
> 1. Is it forbidden for a program to do so because otherwise it will be
> undefined behavior (because it is unspecified what the operator () of
> std::function does after executing the bound functor).

Yes.

>
> 2. Or is it disallowed for implementations to touch anything of "this" after
> invocation of the bound functor because it might have deleted "this"?

No.

This is http://cplusplus.github.io/LWG/lwg-active.html#2224

The bound functor cannot safely/sanely delete "this", since the
std::function is allowed to access
its own members after the call of the bound function. The rule of
thumb is that you
cannot access library types once their destructor has been entered,
even if the core language
allows such access in a limited fashion. Invariants are a library
concept, and once a destructor
of a library type has been entered, invariants are already broken.
Accessing a library type
the invariants of which do not hold is undefined behavior. The
proposed solution might not
be sufficiently clear, but by extension you cannot destroy library
types while such access
is "ongoing".

Johannes Schaub

unread,
Apr 11, 2014, 5:18:29 AM4/11/14
to std-dis...@isocpp.org

Thanks for the link. I agree that to me the resolution regarding this issue is insufficiently clear - in my intuition, the access happenee before the invocation of the bound functor and completed with its invocation entry.

In that regard the nonnormative note which required member function invocation to have finished before the start of the destructor seemed clearer.

David Krauss

unread,
Apr 11, 2014, 5:57:00 AM4/11/14
to std-dis...@isocpp.org

On 2014–04–11, at 5:08 PM, Ville Voutilainen <ville.vo...@gmail.com> wrote:

> This is http://cplusplus.github.io/LWG/lwg-active.html#2224

In addition to the resolution, the word “shared” should probably be struck from the section title because it suggests the restrictions are specific to multithreaded programs.

Also, I agree with Johannes that the new text doesn’t seem as strong as the old note.

Perhaps it should be strengthened with a statement that an access is considered to occur every time control passes through a library member function. This captures the gist of your argument.

Reply all
Reply to author
Forward
0 new messages