Не является ли оптимизация возвращаемого значения (RVO) ошибкой? - PullRequest
7 голосов
/ 11 октября 2010

Я, возможно, задаю глупый вопрос, но я посмотрел на странице википедии RVO здесь и не мог перестать задаваться вопросом, если это поведение неправильно. Я попробовал это на своей машине, и RVO полностью задействован, несмотря на уровень оптимизации. Что если на самом деле что-то BIG произошло в конструкторе? Я знаю, что не должно, но что если? Я не могу понять, почему RVO все еще происходит, когда в конструкторе есть побочные эффекты.

РЕДАКТИРОВАТЬ: -fno-elide-constructors кажется, чтобы остановить RVO. Но вопрос остается.

РЕДАКТИРОВАТЬ2: На более серьезной ноте, сколько людей знают о чем-то вроде этого? Это может быть в стандарте, но это все еще очень уродливая особенность, как я вижу. По крайней мере, компиляторы должны отключить его по умолчанию и предоставить переключатель для людей, которые знают об этом. :)

РЕДАКТИРОВАТЬ 3: Я все еще настаиваю на том, что это действительно плохо. :). Я не думаю, что знаю какие-либо другие языковые ограничения, подобные этим, которые прямо противоречат синтаксису языка. Все остальное выдает ошибки компилятора или компоновщика, верно?

Ответы [ 3 ]

20 голосов
/ 11 октября 2010

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

13 голосов
/ 11 октября 2010

Как сказано в других ответах, компилятору разрешено оптимизировать даже нетривиальные конструкторы копирования и операторы присваивания.

12.8.15

Когдапри соблюдении определенных критериев реализация может опустить конструкцию копирования объекта класса, , даже если конструктор копирования и / или деструктор для объекта имеют побочные эффекты .В таких случаях реализация рассматривает источник и цель пропущенной операции копирования как просто два разных способа обращения к одному и тому же объекту, и уничтожение этого объекта происходит в более поздние времена, когда два объекта были бы уничтожены безоптимизацияЭто исключение операций копирования допускается в следующих обстоятельствах (которые могут быть объединены для исключения нескольких копий):

- в операторе возврата в функции с типом возврата класса, когда выражение является именемВ энергонезависимом автоматическом объекте с тем же типом cv-unqualified, что и тип возвращаемого функцией, операция копирования может быть опущена путем создания автоматического объекта непосредственно в возвращаемое значение функции

- когда временный объект класса, который не имеетпривязанный к ссылке (12.2) будет скопирован в объект класса с тем же типом cv-unqualified, операция копирования может быть опущена путем создания временного объекта непосредственно в цель пропущенной копии

7 голосов
/ 11 октября 2010

Определите «неправильно».Язык C ++ явно разрешает такую ​​оптимизацию, даже если она наблюдаема.Если поведение вашей программы зависит от конкретной реализации, то, к сожалению, вы используете не ISO C ++, а какой-то диалект.

...