Может ли оптимизация компилятора c ++ очистить неиспользуемые структуры данных до окончания области действия? - PullRequest
1 голос
/ 21 января 2020

Рассмотрим следующий код:

#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
}

Я знаю, что это может считаться плохой практикой, и есть лучшие способы написания этого кода, но при условии, что это WIP, и я просто пытаюсь получить его работать, прежде чем тратить время на рефакторинг:

Теоретически возможно ли для компилятора очистить неиспользуемые структуры данных set1, set2, set3, как это предлагается в комментариях (или просто освободить основную память )?

Действительно ли компиляторы так делают?

1 Ответ

2 голосов
/ 24 января 2020

В соответствии с правилом «как будто» компилятор теоретически может удалить неиспользуемые структуры данных, если он может сделать вывод, что их удаление не изменит семантику программы. Для этого компилятор должен доказать, что utility_function не хранит ни один из наборов как часть внутреннего состояния. Он также должен доказать, что переупорядочение построения и уничтожения не будет иметь наблюдаемых эффектов.

Возможность удаления данных компилятором на ранней стадии зависит от задействованных функций, то есть f, utility_function, а также от конструкторов и деструкторов для set.

В качестве ответа на вопрос, который сформулирован только неявно, я настоятельно рекомендую не полагаться на конкретную c оптимизацию для правильности программы. Если вам нужно очистить наборы для набора данных, чтобы они поместились в памяти, вы должны сделать это явно.

...