活跃性分析是否会导致C++对象在离开作用域前被销毁?
关于C++自动变量生命周期与编译器优化的问题
首先明确结论:编译器绝对不允许在赋值b之前销毁v,具体原因如下:
自动变量的生命周期规则
v是定义在example()函数最外层作用域的自动变量,根据C++标准,自动变量的生命周期从定义完成时启动,直到离开其所在的作用域(即example()函数执行完毕、退出整个函数体)才会结束。哪怕代码里在内部块之后不再直接使用v,它的生命周期也不会提前终止。
编译器优化的"as-if"原则
所有编译器优化都必须遵守"as-if"规则:优化后的程序行为必须和未优化的程序行为完全一致。如果编译器提前销毁v,v中的unique_ptr会提前释放所管理的int对象,导致a变成悬空指针,此时访问*a会触发未定义行为——这和原程序预期的(正确读取到1)行为完全矛盾,因此这种优化被C++标准严格禁止。
补充说明
即便代码里不再直接使用v,但a指向的是v内unique_ptr持有的对象,v的销毁会直接影响a的有效性。编译器无法证明提前销毁v不会改变程序的可观察行为,所以绝对不能进行此类优化。
附上你的代码示例:
void example() { vector<unique_ptr<int>> v; v.emplace_back(make_unique<int>(1)); int *a = v.back().get(); { // 后续代码,此段之后不再使用v } int b = *a; }
内容的提问来源于stack exchange,提问作者Materia Gravis
相关产品推荐
相关产品推荐

