4

Let's say I've got a class A

class A {
public:
    A(){};
    ~A(){};
    bool foo(int);
};

bool A::foo(int i){

    if(i==10){
        delete this;
        return true;
    }
    return false;
}

int main(){

    A *pnt = new A();
    if(pnt->foo(10)){
        cout<<"deleted with foo"<<endl;
    }
    else{
        delete pnt;
    }
    return 1;
}

Is this ok or is it undefined behavior that foo will return true?

I'm asking what happens to the member function after "delete this;".

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • 2
    http://stackoverflow.com/questions/3150942/c-delete-this – inetknght Jan 02 '15 at 21:29
  • Reopened: the "duplicate" is about `delete this;` in `void` functions. This question is not whether `delete this;` is OK; it is whether `return true;` is OK after doing `delete this;` . – M.M Jan 04 '15 at 10:58
  • The C++ FAQ entry suggests it is OK but it'd be good to see Standard references – M.M Jan 04 '15 at 11:00
  • 1
    Your member function is not referencing anything belonging to `*this` after deleting `this`, nor does the code in `main`, so it is OK. But it may of course lead to surprises if a different programmer maybe doesn't expect that the object is gone because he never deleted it (be positively sure to name the deleting member function in a way so this is communicated!). Note that you may not access _anything_ belonging to the class instance (not just data fields), including non-static member functions. – Damon Jan 04 '15 at 11:10
  • 1
    The standard says it's OK to `delete this`, period. It does not say it OK to `delete this` only in functions that return `void`. That would be a rather strange and unmotivated restriction. – n. m. could be an AI Jan 04 '15 at 12:01

2 Answers2

1

I searched in draft for current standard and also read the question referenced in comments and the FAQ.

I could not find any elements saying that this code should lead to Undefined Behaviour.

The standard says :

  • the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression : fine this is correct in above code
  • If the value of the operand of the delete-expression is not a null pointer value, the delete-expression will invoke the destructor (if any) for the object : fine, destructor does nothing ...
  • If the value of the operand of the delete-expression is not a null pointer value, then: If the allocation call for the new-expression for the object to be deleted was not omitted and the allocation was not extended (5.3.4), the delete-expression shall call a deallocation function : fine, object will be deallocated

As the code in not in the allocated part of object and as after delete this, code only uses the constant value true, there is no reason for the code to lead to UB. FAQ (and answers to refed question) clearly indicates that delete this is valid and idiomatic C++.

So there is no reason why return true should not be executed.

That being said, as for any other usage of delete this programmer must ensure to use it only on objects allocated with new because if not it is indeed UB.

Community
  • 1
  • 1
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
1

As I understand it 'delete this' makes the object pointed to by the this pointer invalid.

As such it IS undefined to use any member variables; and you can't call virtual (polymorphic) functions (because you don't have a vtable anymore). However you can do anything else that you need to including (as in your case) returning a value.

Elemental
  • 7,365
  • 2
  • 28
  • 33