Как отключить оптимизацию возвращаемого значения в Visual Studio 2010?

Можно ли отключить RVO (оптимизацию возвращаемого значения) в Visual Studio 2010? Установка флага оптимизации на /Od (отключает все оптимизации) не помогает. В g++ существует флаг -fno-elide-constructors, который отключает RVO.


person Goran    schedule 30.03.2012    source источник


Ответы (3)


Вы не можете. Это так просто. RVO/NRVO является стандартным, и ваш код не должен зависеть от его отсутствия.

person Puppy    schedule 30.03.2012
comment
Насколько я могу судить, RVO/NRVO не является стандартом (см. стандарт C++0x, раздел 12.8. Копирование и перемещение объектов класса, параграф 32). Стандарт просто допускает такую ​​оптимизацию (это реализовано в g++ и VisualStudio). У меня нет проблем с этим. Но было бы неплохо иметь какой-нибудь переключатель, чтобы отключить его. Может быть, в образовательных целях. Спасибо, теперь намного понятнее :) - person Goran; 30.03.2012
comment
@Goran: если Стандарт прямо разрешает это, то это Стандарт. - person Puppy; 30.03.2012
comment
Разрешить != требовать. Как таковой он не является частью стандарта, он просто не будет противоречить стандарту. - person Jörgen Sigvardsson; 30.03.2012
comment
@Jorgen: Если включение этого не противоречит Стандарту, то это Стандарт, т. Е. Вы никогда не можете писать код, предполагающий, что он не включен. - person Puppy; 31.03.2012
comment
Если включение не противоречит Стандарту, то это Стандарт. Я думаю, было бы точнее сказать, что тогда это разрешено Стандартом, и это не обязательно означает, что компилятор не должен предоставлять флаг для его отключения. Например, я хотел отключить его в образовательных целях. - person Mark Vincze; 14.08.2014
comment
Это не стандартно. На основе standard draft(N296) 12.8 Copying and moving class object -- 31.3, the copy/move ctor op can be omitted by ..., которые мы здесь называем RVO. Я думаю, это говорит о том, что компилятору разрешено выполнять такую ​​оптимизацию. Но это не обязательно. Таким образом, независимо от того, выполняет ли компилятор RVO или нет, в любом случае следует стандарту. Я неправильно понимаю стандарт? Спасибо. - person Qi W.; 03.04.2016
comment
@Puppy Проблема здесь, то есть то, что, возможно, задает вопрос, и то, что я пришел к вопросу, ищущему, заключается в том, что вы также никогда не можете писать код, который предполагает, что это является включено, потому что стандарт не включает его. Следовательно, компилятор, который предоставляет и уважает возможность отключения, соответствует стандарту с включенной опцией или без нее. Если я хочу написать переносимый код, я могу протестировать свой код как с включенным, так и без него, чтобы убедиться, что он будет работать со всеми стандартными компиляторами. Это проще всего отключить с помощью флага, предоставленного компилятором. - person Jamie S; 13.06.2020
comment
@JamieS Это единственная представленная мотивация, которая действительно имеет смысл. Я мог бы отметить, что это сложно сделать с помощью тестирования, потому что точные ситуации, когда компилятор реализует RVO и друзей, могут различаться между компиляторами или версиями, поэтому предпочтительным вариантом является просто не писать объекты, которые имеют нечистые конструкторы копирования/перемещения. При этом у вас может быть устаревший код и т. Д., Который не делает это правильно. - person Puppy; 19.06.2020

Попробуйте определить свою переменную как volatile, возможно, это решит вашу проблему. Если это не так, вы должны отправить код...

person Malkocoglu    schedule 30.03.2012
comment
+1; хотя это просто случайное предположение (и, как таковое, заслуживает отрицательных голосов), правильно, что return my_volatile_variable; отключает RVO. (С++ 11 §12.8/31 пункт 1.) - person Potatoswatter; 05.01.2013
comment
@Potatoswatter: мне любопытно, почему вы подумали о моем ответе как о случайном предположении. Возможно, в моем ответе означало, что я не был уверен в этом ответе, потому что не знал, в чем была настоящая проблема. ИМХО, этот вопрос в духе мета. stackexchange.com/questions/66377/what-is-the-xy-problem - person Malkocoglu; 07.01.2013
comment
Ах, извините. Я предполагаю, что это причина, по которой они проголосовали за вас. (Лучше обосновать ответ volatile.) - person Potatoswatter; 07.01.2013

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

person AshleysBrain    schedule 30.03.2012
comment
Я могу назвать одну (по крайней мере, для меня) очень важную причину: образование! Как вы объясните студенту конструкторы, конструкторы перемещения/копирования, деструкторы в вызовах функций, когда компилятор опускает их!?! Я очень благодарен g++ за поддержку такой опции. - person Goran; 30.03.2012
comment
Я должен отключить его, чтобы понять время жизни возвращаемого значения, я не могу понять это сейчас, потому что он не создает временное, а просто копирует его прямо. - person Zebrafish; 22.12.2016
comment
@Zebrafish Если вы меняете время жизни возвращаемого значения, чтобы понять время жизни возвращаемого значения, я не думаю, что ваше понимание будет правильным. - person Puppy; 19.06.2020
comment
@Goran Вы учите их неправильно, потому что их понимание внезапно перестанет применяться, когда они попытаются использовать его в реальном мире ... - person Puppy; 19.06.2020