33
votes

I have a hierarchy of base class and derived class. Base class has one virtual function which is overridden by derived class.

class Base
{  
public:  
    ~Base();    
    virtual void other_functionality() = 0;  
};

class Derived : public Base
{  
public:  
    ~Derived ();    
    void other_functionality() {//some code};  
};

Now if i do like this:

int main()
{
Base * P = new Derived ();
delete p;
return 0;
}

It gives error:
deleting object of polymorphic class type which has non-virtual destructor.

But with unique_ptr it passes without warning.

int main()
{
 std::unique_ptr<Base> p;
 p.reset(new Derived ());

return 0;
}

I know if I use virtual destructor. Warning with naked pointer will be solved. But question remains - why absence of virtual destructor shows problem with naked pointer and not with unique_ptr.

2
For the record, clang does complain: godbolt.org/z/qEp6TsMax Langhof
@P.W I don't think this is a duplicate. At least, answers to both questions are different. (Answer to the original question is "because the Stadnard does not require such a check". Answer to this question is "because gcc supresses warnings for system headers".)Daniel Langr
@DanielLangr: The question seemed the same in essence. But the answers do not directly address why the compiler does not issue a diagnostic. So I will reopen.P.W
@gauravbharadwaj it's also in C++17 and pretty much guaranteed to be in C++20. I don't think this question is really specific to any particular version of the language at this point…Michael Kenzel
@gauravbharadwaj I think it is fair that you tagged boost, and that other guy's comment was ridiculously worded. However I also believe the tag is wrong, this is a pure standard C++ matter and you do not even know about the existence of boost to answer this question.ypnos

2 Answers

39
votes

Well, first of all, deleting a derived object through a base pointer when the base class does not have a virtual destructor is undefined behavior. Compilers are not required to diagnose undefined behavior…

That being said, the reason why this warning does not appear when using std::unique_ptr is most likely due to the fact that GCC does not report warnings that would appear in system headers.

20
votes

I cannot find a link, but I did see a discussion of this online, in GCC bug database.

The warning is issued on the actual delete expression. In the case of unique_ptr, the delete is called inside a system header file.

According to the discussion in that bug report, implementing C++ system libraries requires all sorts of compromises that result in various warnings. Therefore, the warnings are restricted inside system headers. That is the reason you won't see the warning you expect.

Update: and here it is, straight from the horse's mouth:

https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

The header files declaring interfaces to the operating system and runtime libraries often cannot be written in strictly conforming C. Therefore, GCC gives code found in system headers special treatment. All warnings, other than those generated by ‘#warning’ (see Diagnostics), are suppressed while GCC is processing a system header.