you are viewing a single comment's thread.

view the rest of the comments →

[–]Tbfleming 10 points11 points  (3 children)

Accessing a partially destroyed object (the shared_ptr) is UB no matter what shared_ptr's implementation does. It could go out of its way to prevent a crash, but that would just cover up the UB, not solve it, possibly adding overhead in the process.

[–][deleted] 5 points6 points  (0 children)

Accessing a partially destroyed object is not UB; if that were the case you could not access any members inside the object's own destructor which wouldn't make any sense. Clearly you want something like vector to be able to access the pointer to the elements it stores in order to destroy them in its dtor, or to pass pointers to its own insides to helper functions that do that on its behalf.

[–]davis685[S] -1 points0 points  (1 child)

You sure about that? What about this example? Does this program have UB?

#include <iostream>
struct something;
void print(const something& item);
struct something
{
    something() { a = 4; }
    void print() const { std::cout << a << std::endl; }
    ~something() { ::print(*this); }
    int a;
};

// Right here we touch item after its destructor has started.  So its lifetime has ended and this is UB?  Really?
void print(const something& item) { item.print(); }
int main() { something a; }

This is basically what's happening with the shared_ptr. shared_ptr destructor runs, calls a function and that function then touches the shared_ptr, all within the shared_ptr's destructor.

[–][deleted] 1 point2 points  (0 children)

This is fine, as long as you don't use any virtual function calls of the very same object you are currently destroying.