除以零在虚拟析构函数中工作正常
Division by zero works fine in virtual Destructor
#include <iostream>
using namespace std;
static int i=1;
class Parent
{
public:
virtual ~Parent(){10/i;}
};
class Child: public Parent
{
public:
virtual ~Child(){--i;}
};
int main()
{
Parent *ptr = new Parent;
Parent *ptr1 = new Child;
delete ptr;
delete ptr1;
//cout<<10/i;
return 0;
}
为什么父类的虚拟析构函数不提供任何运行时错误?而代码的注释部分在取消注释时会引发错误。
我想您的编译器优化了代码并删除了无用的部分,包括基类析构函数中的10/i
。
试试这个:
#include <iostream>
using namespace std;
static int i=1;
class Parent
{
public:
virtual ~Parent(){int tmp = 10/i; cout << tmp; }
};
class Child: public Parent
{
public:
virtual ~Child(){--i;}
};
int main()
{
Parent *ptr = new Parent;
Parent *ptr1 = new Child;
delete ptr;
delete ptr1;
//cout<<10/i;
return 0;
}
未定义的行为是未定义的,因此任何事情都可能发生。
没有副作用的语句对于编译器来说微不足道,因此它甚至不会尝试执行基析构函数内部的内容。
把它放在cout
是另一回事——你都试过吗?
尽管没有可观察到的行为,编译器很容易证明--i
语句后面总是跟着 10/i
,这反过来意味着不能i==1
调用--i
。
由于i
对翻译单元是静态的,因此优化器还知道没有其他代码更改i
其初始值 1
。
因此,现代优化器可以证明Child::~Child
也没有被调用。
反过来,这意味着无法访问main
的第四行。这是事情变得非常有趣的地方。 main
似乎没有分支,但对于编译器来说并非如此。 new
可能会抛出,这会为该程序引入两个分支。由于"通常"的非异常分支无法证明无法执行,优化器可能会得出结论,唯一可访问的分支是 2,其中任一语句new
抛出 (!)
相关文章:
- 在析构函数之后,围绕成员函数的C++lambda包装器是如何工作的
- 当我使用dynamic_cast并删除对象删除时,析构函数是如何工作的?
- 程序按执行方式工作,直到我向其添加析构函数为止
- 在删除另一个类中的一个类的对象时析构函数如何工作
- 构造函数和析构函数的工作原理
- 构造函数和析构函数之间的"unexpected"配对。为什么要这样工作?
- C++:析构函数内部如何工作以及谁调用默认析构函数
- 析构函数如何工作
- unique_ptr类型擦除析构函数不能正常工作(带有警告)
- 除以零在虚拟析构函数中工作正常
- 我无法让我的析构函数在我的代码中工作
- C++基于堆栈的构造函数/析构函数无法按预期工作
- 析构函数在c++中的工作方式
- 在虚拟析构函数的情况下,虚拟机制是如何工作的
- std::swap在构造函数、赋值运算符和析构函数方面是如何工作的
- c++中的虚析构函数是如何工作的
- 虚拟析构函数和删除具有多重继承的对象..它是如何工作的
- 析构函数之前可以工作.如何去做
- 代码可以工作,但在析构函数中崩溃(没有复制构造函数)
- C++类析构函数无法正常工作