【问题标题】:C++ inplace destructor compile warningC ++就地析构函数编译警告
【发布时间】:2017-05-17 10:02:03
【问题描述】:

我在我的代码中使用了就地析构函数,类似于这段精简的代码:

#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 中给了我一个警告,包括调试和发布:

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

尽管在 g++ 中编译良好,即使使用 -Wall。知道为什么我会收到警告吗?这可能是编译器中的错误吗? b 在b-&gt;~Node() 调用中明显使用。

当我将 Node 实现更改为此时,它似乎也可以正常编译:

struct Node {
    ~Node() {
    }
};

但据我所知,这应该没什么区别。

【问题讨论】:

  • 嗯,我的猜测是优化器完全忽略了对默认析构函数的调用,然后得出结论,从未使用过 b。您是仅在编译优化的构建时看到此警告,还是在未优化/调试的构建中也看到它?
  • 它也在调试版本中
  • 有趣。是的,我在 32 位和 64 位版本以及 VS 2010、2012 和 2015 上都启用和禁用了优化器。这对我来说似乎是一个错误,除非我还遗漏了一些明显的东西。 (它在优化构建中省略了对析构函数的调用,当然,事实上,也省略了对构造函数的调用。目标代码仅调用mallocfree。)
  • 很明显,b 正在被使用。因此这是一个编译器错误。
  • 我也投票支持编译器错误。

标签: c++ visual-studio visual-studio-2015 destructor compiler-warnings


【解决方案1】:

C++ 中没有编译器警告标准。因此,每个编译器都可以在他想要的任何地方警告您,这是一个选择问题

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

【讨论】:

    【解决方案2】:

    Trivial destructor

    如果满足以下所有条件,则类 T 的析构函数是微不足道的:

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

    普通析构函数是不执行任何操作的析构函数。具有普通析构函数的对象不需要删除表达式,可以通过简单地释放它们的存储空间来处理。

    【讨论】:

      猜你喜欢
      • 2010-09-12
      • 2015-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多