Hongxu Chen Hongxu Chen - 3 months ago 8
C++ Question

clang & gcc don't warn about non-virtual base destructors for polymorphism when using smart pointers?

We know that if there are virtual functions then the base class destructor should be marked as virtual as well, otherwise it is undefined behavior when explicitly

deleted
with base class pointer if we hope to delete derived object with base class pointer the base destructor should be marked as virtual, otherwise it is undefined behavior.

For example,

struct Base {
virtual void greet() { std::cout << "base\n"; }
};

struct Derived : public Base {
virtual void greet() override { std::cout << "derived\n"; }
};


call

Base *b = new Derived;
b->greet();
delete (b);


clang(gcc similarly) will emit such a warning when -Wdelete-non-virtual-dtor:

delete called on 'Base' that has virtual functions but non-virtual destructor


But neither of them report warnings for smart pointers:

std::unique_ptr<Base> sb = std::make_unique<Derived>();
// std::unique_ptr<Base> sb = std::unique_ptr<Derived>(new Derived);
sb->greet();


I guess this still leads to undefined behavior, right?

Answer

Yes, it's still undefined behavior. The problem is that the delete call happens inside std::default_delete, which is inside a system header. By default, the compiler doesn't generate warnings for code in system headers.

If you pass -Wsystem-headers, you'll see the warning. Unfortunately, it's buried inside a pile of other warnings.

Comments