7

我用我的代码就地析构函数,类似这样的精简一段代码:C++就地析构函数编译警告

#include <new> 
#include <stdlib.h> 

struct Node { 
}; 

int main(int, char**) { 
    Node* a = reinterpret_cast<Node*>(malloc(sizeof(Node))); 
    new(a) Node; 

    Node* b = a; 
    b->~Node(); 

    free(a); 
} 

不幸的是这给了我在Visual Studio 2015年警告,无论是在Debug和Release :

warning C4189: 'b': local variable is initialized but not referenced

它编译罚款虽然G ++,甚至-Wall。任何想法为什么我得到警告?可能这是编译器中的一个错误? b清楚地在b->~Node()呼叫中使用。

它也似乎当我改变的节点执行这个编译罚款:

struct Node { 
    ~Node() { 
    } 
}; 

但据我可以说,这不应该有所作为。

+1

嗯,我的猜测是,优化器完全抛弃了对默认析构函数的调用,然后得出结论认为'b'永远不会被使用。只有在编译经过优化的版本时才会看到此警告,或者您是否在未优化/调试版本中看到此警告? –

+0

它也在调试版本 – martinus

+0

有趣。是的,我在优化器启用和禁用的情况下对32位和64位版本以及VS 2010,2012和2015进行了重新编译。对我来说看起来像是一个bug,除非我还缺少一些明显的东西。 (当然,它*是*在优化构建中消除了对析构函数的调用,事实上,它也消除了对构造函数的调用。目标代码只调用'malloc'和'free'。) –

回答

2

在C++中没有关于编译器警告的标准。因此,每个编译器都可以在任何地方提醒你,这是一个选择问题

在你的情况下,警告确实有意义,因为默认析构函数可能不会将视为引用(例如:所有局部变量在其作用域的末尾被默认销毁)。

2

Trivial destructor

类T的析构函数是平凡的,如果满足以下所有的条件为真:

  • 析构函数不是用户提供的(意思是,它要么是隐式地声明,或明确定义为默认第一个声明)
  • 析构函数不是虚拟的(也就是说,基类析构函数不是虚拟的)
  • 所有直接基类都有微不足道的析构函数
  • 类类型(或类类型数组)的所有非静态数据成员都有微不足道的析构函数。

一个微不足道的析构函数是一个不执行任何操作的析构函数。带有琐碎析构函数的对象不需要delete-expression,并且可以通过简单地释放其存储来处理。