Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I access 'this' from a constructor's function-try handler?

About the following code :

class C {
    C() try {
        void* addr = this;
        add_addr_to_static_structure(addr);
        // May throw exception
    } catch(...) {
        void* addr = this; // <- Can I access this ?
        remove_addr_from_static_structure(addr);
    }
};

I know from https://en.cppreference.com/w/cpp/language/try that I cannot call a method of the object. I can only call static methods.

Referring to any non-static member or base class of an object in the handler for a function try block of a constructor or destructor for that object results in undefined behavior.

From ISO c++ 15.3.10 : Why is this undefined behaviour?, this is because members will be destroyed before we enter the handler.

However, can I access this (as a simple value) without dereferencing it, or is this not guaranteed to be valid?

like image 883
mgautierfr Avatar asked Sep 02 '25 14:09

mgautierfr


1 Answers

Evaluating this is never UB, but this can sometimes be an invalid pointer value under [basic.compound]/4:

A pointer value P is valid in the context of an evaluation E if P is a pointer to function or a null pointer value, or if it is a pointer to or past the end of an object O and E happens before the end of the duration of the region of storage for O. If a pointer value P is used in an evaluation E and P is not valid in the context of E, then the behavior is undefined if E is an indirection ([expr.unary.op]) or an invocation of a deallocation function ([basic.stc.dynamic.deallocation]), and implementation-defined otherwise.

For example, if the constructor has evaluated delete this;, then this will have become an invalid pointer value because the storage pointed to by this has been deallocated. Any further uses of this will be implementation-defined and this could mean a segmentation fault or trap on some platforms.

Entering the function try block of the constructor does not make this an invalid pointer value as no operation has yet occurred that would deallocate the storage. For example, if the object being constructed has automatic storage duration, the storage for it lasts until the caller's block has exited ([basic.stc.auto]/1), which won't happen until the function try block rethrows the exception. As long as you're still in the function try block, the constructor is still executing.

like image 123
Brian Bi Avatar answered Sep 05 '25 05:09

Brian Bi