保留派生类引用的基类的std :: unique_ptr在gcc编译器中不显示警告,而裸指针显示它。为什么?

gau*_*waj 34 c++ gcc-warning c++14

我有一个基类和派生类的层次结构。基类具有一个虚函数,该虚函数被派生类覆盖。

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

class Derived : public Base
{  
public:  
    ~Derived ();    
    void other_functionality() {//some code};  
};
Run Code Online (Sandbox Code Playgroud)

现在,如果我这样做:

int main()
{
Base * P = new Derived ();
delete p;
return 0;
}
Run Code Online (Sandbox Code Playgroud)

它给出错误:
删除具有非虚拟析构函数的多态类类型的对象。

但是使用unique_ptr,它会通过而不会发出警告。

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

return 0;
}
Run Code Online (Sandbox Code Playgroud)

我知道我是否使用虚拟析构函数。用裸露的指针警告将得到解决。但是问题仍然存在-为什么没有虚拟析构函数会显示裸指针而不是unique_ptr问题。

Mic*_*zel 40

好吧,首先,当基类没有虚拟析构函数时,通过基指针删除派生对象是未定义的行为。不需要编译器来诊断不确定的行为…

话虽如此,使用时未显示此警告的原因std::unique_ptr很可能是由于GCC 没有报告会出现在系统标题中的警告


小智 21

我找不到链接,但是在GCC错误数据库中确实看到了有关此链接的讨论。

警告在实际delete表达式上发出。如果是unique_ptrdelete则在系统头文件中调用。

根据该错误报告中的讨论,实现C ++系统库需要各种妥协,从而导致各种警告。因此,警告仅限于系统头文件内。这就是您看不到预期警告的原因。

更新:就在这里,从马的嘴巴开始:

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

声明与操作系统和运行时库的接口的头文件通常不能严格按照C语言编写。因此,GCC对在系统头中找到的代码给予特殊对待。在GCC处理系统标头时,所有警告(由“ #warning”生成的警告除外)(请参阅诊断)均被抑制。