Topic: Continue processing after a `delete this


Author: tom@smart.bo.open.DE (Thomas Neumann)
Date: 11 May 93 19:47:33
Raw View
>>|Is this legal ?
>>|
>>|#include <iostream.h>
>>|
>>|struct A {
>>|   A() {}
>>|   void doit() {
>>|      delete this;
>>|      int i;
>>|      for (i = 0; i < 10; i++)
>>|     cout << i << endl;
>>|   }
>>|};
>>|
>>|int main() { A a; a.doit(); return 0; }
>>

  FJH> Oops, I didn't read the example carefully enough. Of course
  FJH> it's illegal, it tries to delete an automatic object.  Suppose
  FJH> however that we amend main() to read

  FJH>  int main() { (new A)->doit(); return 0; }

  FJH> Does this make the example legal?

I'm the poster of the original article that brought up this question.
Of course, I goofed in main() and is was supposed to read as you show
in your corrected example.

The focus on the question of legality of course remains the doit() member
function, so the question still stands: Is it legal ?
It would be nice the see justified answers, not just `yes' or `no'.

Thank you.

--
"There is a regular expression that can do it in one pass, but if you learn
it you'll turn into an expert, and we've already got too many of those."
  -- Larry Wall




Author: daniels@NeoSoft.com (Brad Daniels)
Date: Wed, 12 May 1993 13:43:07 GMT
Raw View
In article <TOM.93May11194733@smart.bo.open.DE> tom@smart.bo.open.DE (Thomas Neumann) writes:
>
>>>|Is this legal ?
>>>|
>>>|#include <iostream.h>
>>>|
>>>|struct A {
>>>|   A() {}
>>>|   void doit() {
>>>|      delete this;
>>>|      int i;
>>>|      for (i = 0; i < 10; i++)
>>>|     cout << i << endl;
>>>|   }
>>>|};
>>>|
>  FJH>  int main() { (new A)->doit(); return 0; }
>
>The focus on the question of legality of course remains the doit() member
>function, so the question still stands: Is it legal ?
>It would be nice the see justified answers, not just `yes' or `no'.
>

Yes and no.  <-- Note left-justified answer, which is neither yes nor no... :-)

But seriously...  The draft working document for C++ says in section 5.3.3:
"The effect of attempting to access a deleted object is undefined and the
deleteion of an object may change its value..."

This means that you can't access any part of a deleted object after the
delete operation...  The fact that it's undefined, though, means that it
could potentially work.   The working draft of the standard does not
explicitly comment as to whether continuing to execute a member function
within an object constitutes "access" to the object, though it is clear on
what other things constitute access.  Assuming that I didn't miss the place
where the working draft comments on whether continuing execution constitutes
access to an object, we can consider the behavior of your code to be undefined.

In that code, however, you don't access any member functions or
data members after the deletion, so in any reasonable implementation, you
should be able to continue executing.  Since this kind of construct may be
useful in some cases (e.g. if deletion has side-effects which must happen
before some additional operations on shared resources which should only
take place when the object gets deleted on certain code paths), it may be
advisable for the standard to state explicitly that continued execution
does not constitute access.  Of course, a language lawyer might say that
by not mentioning continued execution as a form of access, the standard
implicitly says that it is not a form of access and is therefore defined
to work, but it is very difficult to determine the non-existence of in-
formation in a standard, so there should probably be an explicit statement
on this subject.  Perhaps a brief listing of the ways an object can be
accessed should be added to section 5.2.4 on class member access.  Then,
anything not on that list could be considered explicitly not defined as
access, simplifying the task of determining that the standard does not
define it as such.  An explicit statement that continued execution is not
in itself access would then be unnecessary, but could be added for clarity's
sake.

- Brad
--
Brad Daniels  ` |  "If money can't buy happiness,
daniels@neosoft.com  |   I guess I'll have to rent it."
I don't work for NeoSoft, and |  - Weird Al Yenkovic
don't speak for my employer. |




Author: fjh@munta.cs.mu.OZ.AU (Fergus James HENDERSON)
Date: Sun, 9 May 1993 16:27:27 GMT
Raw View
I wrote:

>jimad@microsoft.com (Jim Adcock) writes:
>
>>tom@smart.bo.open.DE (Thomas Neumann) writes:
>>|Is this legal ?
>>|
>>|#include <iostream.h>
>>|
>>|struct A {
>>|   A() {}
>>|   void doit() {
>>|      delete this;
>>|      int i;
>>|      for (i = 0; i < 10; i++)
>>|  cout << i << endl;
>>|   }
>>|};
>>|
>>|int main() { A a; a.doit(); return 0; }
>>
>>No.
>
>Can you justify your answer? I want chapter and verse :-)
>from either the ARM or the current working papers.
>
>Certainly the ARM specifies that _calling_ a member function on something
>that is not an object is undefined, but I can't find anything prohibiting
>_continuing execution_ in a member function when *this is no longer
>an object, or anything prohibiting _returning_ from the function.

Oops, I didn't read the example carefully enough. Of course it's illegal,
it tries to delete an automatic object.
Suppose however that we amend main() to read

 int main() { (new A)->doit(); return 0; }

Does this make the example legal?

--
Fergus Henderson                     This .signature virus might be
fjh@munta.cs.mu.OZ.AU                getting old, but you still can't
                                     consistently believe it unless you
Linux: Choice of a GNU Generation    copy it to your own .signature file!