c++ - 为什么要为未删除的对象调用析构函数?

标签 c++ language-lawyer

struct A
{
    ~A() = delete;
};

int main()
{
    new A{};
}

编译失败并显示错误信息:

error: use of deleted function 'A::~A()' new A{};

据我所知,我并没有销毁对象,那么它为什么要尝试调用析构函数?

编译 GCC 8.1.0

g++ -std=c++17 -O2

最佳答案

这是gcc bug 57082 .


让我们从下往上。

[dcl.fct.def.delete]/2 :

A program that refers to a deleted function implicitly or explicitly, other than to declare it, is ill-formed.

显然,我们并没有明确提及 ~A()。我们是否隐含地提到它? [class.dtor]/12 :

A destructor is invoked implicitly

  • for a constructed object with static storage duration ([basic.stc.static]) at program termination ([basic.start.term]),
  • for a constructed object with thread storage duration ([basic.stc.thread]) at thread exit,
  • for a constructed object with automatic storage duration ([basic.stc.auto]) when the block in which an object is created exits ([stmt.dcl]),
  • for a constructed temporary object when its lifetime ends ([conv.rval], [class.temporary]).

或在 [expr.new]/20 :

If the new-expression creates an array of objects of class type, the destructor is potentially invoked.

我们有这些东西吗?不,这里没有自动、静态或线程存储持续时间的对象,也没有构造的临时对象,我们的 new-expression 也没有创​​建数组。这里只有一个对象,即我们正在聚合初始化的具有动态存储持续时间的 A

由于我们既没有显式也没有隐式引用 ~A(),所以我们不能违反该规则。因此,gcc 错误。另请注意,gcc 接受 new A;new A();,就本规则而言,它们具有相同的含义。

关于c++ - 为什么要为未删除的对象调用析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51974783/

相关文章:

c++ - 从辅助线程调用 UpdateWindow()

c++ - std::is_constructible<void()>::value 的正确结果是什么?

c++ - 了解这个可变参数模板函数是如何工作的

c# - 异常助手不工作

c++ - 快速调用 fread 会使应用程序崩溃

c++ - 在 32 位架构上优化可移植的 128 位整数移位

python - =+ Python 运算符在语法上是正确的

c++ - Clang 和 GCC 不同意使用转换运算符直接初始化的合法性

c - 相邻的字符和字符串文字标记

c++ - 抑制 C++ 中未使用的变量警告 => 编译器错误或代码错误?