Когда у меня есть цикл, и внутри этого цикла создается новая переменная стека (без выделения ее в куче и переменной, содержащей ее, объявленной внутри тела цикла), гарантированно вызывается деструктор этого объекта перед началом следующей итерации, или может Развертывание цикла компилятором что-то изменит?
c++
destructor
user1282931
источник
источник
Ответы:
От
n4800
:§6.3.3 Объем блока :
§10.3.6 Деструкторы :
§4.1.1 Абстрактная машина :
[Акцент мой]
Так да. Ваша переменная выходит из области видимости в конце цикла (который является блоком), и, следовательно, ее деструктор вызывается настолько, насколько каждый может наблюдать за поведением программы .
источник
call
. Или, если они эффективно (как если бы правило) ничего не делают, может не быть сборки для таких генерируемых деструкторов.Да. Это проще визуализировать, когда вы рассматриваете «блоки», в которых вы объявляете переменную, т.е. между какой парой скобок. Цикл сам по себе является блоком, и, когда он достигает закрывающей скобки, перед следующей итерацией вызываются все деструкторы переменных автоматического хранения, объявленные в цикле.
Как правило, не думайте о том, что компилятор будет оптимизировать, потому что он все еще должен гарантировать поведение вашей программы, независимо от того, что он делает для ее оптимизации. В этом случае развертывание цикла ничего не изменит в этом случае, если это произойдет.
источник
[class.copy.elision]
for(...) X x{};
иx
объект будет построен + разрушен в каждой итерации. Живая демоверсия . Соответствующим Стандартным разделом является stmt.iter / 2 .[stmt.iter]
это чисто эквивалентно (выделено мое): «Если подстановка в выражении итерации является одним оператором, а не составным оператором, это как если бы оно было переписано, чтобы быть составным оператором, содержащим оригинальное утверждение . По сути, с или без скобок для одного утверждения означает абсолютно то же самое, и скобки являются неявными. Я опустил это для ясности.Деструктор вызывается для каждой итерации. Таким образом, в некоторых случаях быстрее объявить переменную вне цикла, а не в цикле. Предполагая следующий случай:
Деструктор не вызывается при использовании цикла. Это просто отменяет
temp
.Но если вы используете
std::string temp = arr[i]
конструктор и деструктор вызывается для каждой итерации. Я думаю, что это добавляет немного времени выполнения, если у вас есть цикл, который выполняется очень часто.источник
Деструктор вызывается перед следующей итерацией
источник
Конечно, dtor вызывается в конце итерации, и развертывание цикла не должно изменять это поведение, как любая другая оптимизация (оптимизация не должна изменять поведение программы), за исключением некоторого вида RVO и т. П., Которые могут устранить некоторые семантически ложные создания объектов ,
источник