C++ Can c++;编译器优化在作用域结束前清除未使用的数据结构?
考虑以下代码:C++ Can c++;编译器优化在作用域结束前清除未使用的数据结构?,c++,memory,compiler-optimization,C++,Memory,Compiler Optimization,考虑以下代码: #include <set> template <int n> std::set<int> utility_function(std::set<int> const & input){ // ... } void f(std::set<int> && set1){ std::set<int> set2 = utility_function<1>(set1)
#include <set>
template <int n>
std::set<int> utility_function(std::set<int> const & input){
// ...
}
void f(std::set<int> && set1){
std::set<int> set2 = utility_function<1>(set1);
// set1.clear();
std::set<int> set3 = utility_function<2>(set2);
// set2.clear();
std::set<int> set4 = utility_function<3>(set3);
// set3.clear();
// ... use set4, without refering to set1, set2, set3
}
#包括
模板
标准::设置实用工具函数(标准::设置常量和输入){
// ...
}
空f(标准::集和集1){
std::set set2=实用工具功能(set1);
//set1.clear();
std::set set3=实用工具功能(set2);
//set2.clear();
std::set set4=实用工具功能(set3);
//set3.clear();
//…使用set4,不参考set1、set2、set3
}
我知道这可能被认为是一种不好的做法,有更好的方法来编写此代码,但假设这是一个WIP,我只是想在浪费时间进行重构之前让它正常工作:
从理论上讲,编译器是否可以按照注释中的建议清除未使用的数据结构set1
、set2
、set3
(或者干脆释放底层内存)
编译器真的这样做了吗?根据“好像”规则,理论上编译器可以删除未使用的数据结构,前提是可以推断删除它们不会改变程序的语义。为此,编译器必须证明
utility\u函数
没有将任何集合作为内部状态的一部分。它还必须证明,重新排序的建设和破坏将不会产生明显的影响
编译器是否会提前删除数据取决于所涉及的函数,即f
,utility\u函数
,以及set
的构造函数和析构函数
作为对一个问题的回答,我强烈建议不要依赖特定的优化来保证程序的正确性。如果需要清除数据集的集合以适应内存,则应明确执行此操作。不知道
实用程序功能的内容,通常不能<代码>实用程序函数
可以存储和访问指向向量的指针/引用/迭代器。您可能想给出一个更具体的例子。考虑到效用函数
按值返回,这意味着它返回向量的副本,该副本将是独立的或原始向量。但是,正如前面提到的,我们不知道utility\u函数
还做了什么,也不知道f
返回后会发生什么,编译器也不知道。另外,编译器为什么要清除向量<当函数f
结束时,代码>v2、v3
和v4
将被“清除”,因为它们被销毁。没有一个编译器会做一些它没有要求的事情,它不会清除或释放任何动态分配的内存,比如向量的内存。使用“仿佛”规则,它可能会在以前清除,但我怀疑任何编译器会这样做。同样重要的是要知道,如果编译器可以推断在第三次调用utility_function
后,v2
和v3
都不会被再次使用,那么它可以生成代码来立即销毁这些对象,但这很难检查,而且很可能不会发生。