Почему RVO не происходит для оператора присваивания? (C++)

Пример:

A myfunction() { return A(); }
A a = myfunction(); // default ctor only (return value optimization)
a = myfunction(); // default ctor and operator=

Почему компилятор не может просто записать новый объект в существующий объект? Я считаю, что все экземпляры класса занимают одинаковое количество (не динамической) памяти, поэтому я не понимаю, почему это может быть проблемой.

2 ответа

Решение

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

Нет такой специальной лицензии, чтобы игнорировать побочные эффекты в операторе присваивания, поэтому ее нельзя опускать. Кроме того, так как a действителен до того, как ему присвоено, его сначала нужно будет уничтожить, чтобы можно было построить новый объект на месте. Мало того, что не существует специальной лицензии для игнорирования побочных эффектов, вызванных этим вызовом деструктора, что хуже, что разрушение должно произойти до вызова функции, а затем, где вы будете, если функция сгенерирует?

RVO работает путем построения возвращаемого значения в кадре стека вызывающей стороны.

В первом случае его можно построить непосредственно в хранилище для a, поскольку там еще нет объекта.

Во втором случае там уже есть объект, поэтому его нужно будет построить где-то еще, прежде чем назначить a, Вы не можете построить новый объект поверх a, поскольку это не так, как назначение.

Другие вопросы по тегам