Правильный синтаксис для вызова деструктора:
template<typename T>
void destruct(T& x)
{
x.~T(); // call destructor on x
}
// The below is valid even though ints do not have destructors
int x;
destruct(x);
Этот синтаксис действителен для типов, таких как int (при передаче в качестве параметра шаблона), но он не используется (ничего не делает), поэтому допустим код шаблона, такой как в std::vector<T>
, который вызывает деструкторы для своего содержимого.
IMO для компилятора должно быть просто увидеть, что содержимое цикла содержит запрет, поэтому весь цикл не имеет побочных эффектов, поэтому удалите весь цикл. Современные компиляторы имеют очень сложные оптимизаторы и должны быть более чем способны удалить код, который не имеет никакого эффекта. Если компилятор не не удаляет избыточные циклы, он будет генерировать избыточный код в деструкторе vector<int>
! Для деструктора типа int не существует кода, который нужно выдать, поэтому будет просто пустой цикл, повторяющий элементы, которые ничего не делают. Я уверен, что любой здравомыслящий оптимизатор удалит весь этот цикл.
Конечно, если вы вызываете деструктор для класса, который действительно работает в его деструкторе, он все равно должен быть вызван, и все равно будет цикл (с учетом других связанных оптимизаций, таких как развертывание).
Другим простым примером оптимизации на основе побочных эффектов является код, подобный следующему:
for (int i = 0; i < 1000000; ++i)
; // just count up i, no statement (same as no-op)
cout << i;
, вероятно, будет оптимизирован для простой печати константы 1000000 без обработки, поскольку компилятор достаточно умен, чтобы знать, что общий побочный эффект - i
становится миллионным и печатается. Это основа для некоторых из впечатляющих вещей, которые делают оптимизаторы, так что не беспокойтесь об этом, это сделает отличную работу. Если вам когда-нибудь интересно, изучите выходную сборку в оптимизированной сборке, чтобы увидеть, что на самом деле происходит.