销毁静态存储持续时间对象和未定义的行为
destruction of static storage duration objects & undefined behavior
c++标准第3.6.1节规定
调用在
<cstdlib>
中声明的函数std::exit(int)
终止程序不会离开当前块,因此不会销毁所有具有自动存储期限的对象在对象的销毁过程中被调用来结束程序静态存储期间,程序有未定义行为。
那么,考虑下面这个简单的程序
#include <iostream>
#include <cstdlib>
class test
{
public:
test()
{
std::cout<<"constructorn";
}
~test()
{
std::cout<<"destructorn";
}
};
int main()
{
test t;
exit(0);
}
上面程序的输出显然应该是
构造函数
那么,我的问题是:
自动对象t何时会被销毁?
编译器会安全地销毁它吗?
为什么是未定义行为?
现在,考虑上面程序的稍微修改版本。
#include <iostream>
#include <cstdlib>
class test
{
public:
test()
{
std::cout<<"constructorn";
}
~test()
{
std::cout<<"destructorn";
}
};
int main()
{
static test t;
exit(0);
}
现在,我得到以下输出:
构造函数析构函数
所以,有可能看到只有构造函数调用作为输出在一些c++实现由于未定义的行为?
如果我理解错了,请纠正我。
- 自动对象何时会被销毁?
从来没有。你引用的那句话是"……没有销毁任何具有自动存储持续时间的对象…"
- 编译器会安全地销毁它吗?
。编译器的工作是生成供机器运行的代码,一旦你进入运行时,编译器就不再做任何事情了。
- 为什么是未定义行为?
在您的示例中,这不是未定义的行为-您没有在"销毁具有静态或线程存储持续时间的对象"期间调用std::exit()
。然而,如果您是,那么回答"这是未定义的行为,因为标准明确地说明了这一点"就足够了。
相关文章:
- 在销毁期间从另一个线程调用对象上调用方法是否未定义行为?
- 为什么销毁被放置 new 覆盖的对象不是未定义的行为?
- 未定义的对象(〔basic.life〕/8):为什么允许引用重新绑定(和常量修改)
- 正在通过const-ref未定义的行为捕获新构造的对象
- 仅标头类 + 仅当返回该类的对象时,对函数的未定义引用
- 如果用户尝试从 JS 调用对象的未定义函数C++则回调C++代码
- C++:在共享对象中调用抽象基类构造函数/未定义的符号
- Cython:共享对象中未定义的符号
- 对"车辆的 vtable"的未定义引用 - 面向对象的编程练习
- 为什么内置类型的对象上的溢出会导致异常/未定义的行为?
- 正在加载共享对象:文件中未定义版本Qt_5
- 对象文件中的未定义引用 - 如何查找哪个库包含它
- static_cast实际上不是对象类型的类型是未定义的行为吗?
- 尝试与从 CUDA 对象构建的共享库链接时未定义的符号
- C++ / G++ Maxmind geolite2++ 第三方共享对象未定义引用
- 对象在函数中未定义
- C++ 未定义的对象引用
- 通过在此指针上放置新位置重新初始化对象时未定义的行为
- 将不相关类型的对象reinterpret_cast空类是未定义的行为吗?
- 未分配返回未定义对象类型引用的 C++ 函数的返回值时会发生什么情况