my_class f(bool b) {my_class c; if(b){return my_class();} else {return c;} } ← как здесь в момент компиляции вычислить какой из двух объектов нужно конструировать на месте объекта, которому происходит присваивание?
а не надо во время компиляции ничего конструировать. каждый return получит свой RVO. первый будет создавать дополнительный объект, а второй не будет (т.к. этот объект будет конструироваться всегда). ведь RVO заключается в том, что при возвращении они не обязаны копироваться, так? тогда не вижу проблем.
а теперь расскажи, как это объекты не будут копироваться, если у тебя в функции могут конструироваться два объекта, и при этом только один должен быть возвращён?
f1 — это функция, которую должен оптимизировать компилятор. f2 — то, как я себе представлял, что он это сделает. таки да, в первом случае одно копирование имеет место быть, во втором — ни одного. если я мудак и это вообще бред — прошу объяснить.
что тебе объяснить? что ты мудак? это следует из того что поведение компилятора отличается в лучшую сторону от того что ты от него ожидал. ну и из того что ты два copy c'tor'а написал
ну короче хоть мне и непонятно еще почему именно невозможно оптимизировать иначе, но я понял, что при NRVO нужно как минимум возвращать "the same named object". про этом это не исключает возможность использоваться много return'ов, при этом имея RVO ни разу.
про невозможность оптимизации NRVO при разных named object'ах теперь мне понятно (хотя если эти named object'ы используются в непересекающихся ветвях возврата, то вполне можно было бы и оптимизировать, просто видимо сложно дохуя)
pred()?a:b;
не работает если b не приводимо к a
if (pred()) return a;
return b;
питонист дохуя?
Перлоёб. А причём тут это?
я первый вариант использую.
Первый, конечно. И ворнинга не будет от особо въедливых концпеляторов.
у питонистов за токое варнинг получишь
помнится, на хабре был человек, люто доказывающий, что return у функции должен быть лишь один. много смеялись)
смеялись много те, кто не знает что такое RVO
Как вообще количество return'ов влияет на наличие/отсутствие RVO?
напрямую. один return — может быть RVO, else — не может.
но почему не может? не вижу причин.
my_class f(bool b) {my_class c; if(b){return my_class();} else {return c;} } ← как здесь в момент компиляции вычислить какой из двух объектов нужно конструировать на месте объекта, которому происходит присваивание?
а не надо во время компиляции ничего конструировать. каждый return получит свой RVO. первый будет создавать дополнительный объект, а второй не будет (т.к. этот объект будет конструироваться всегда). ведь RVO заключается в том, что при возвращении они не обязаны копироваться, так? тогда не вижу проблем.
а теперь расскажи, как это объекты не будут копироваться, если у тебя в функции могут конструироваться два объекта, и при этом только один должен быть возвращён?
я думал будет что-то вроде http://paste.ubuntu.com/993930/
ну, или даже проще. суть ясна. оптимизация в том, чтоб во время return устанавливать значение в указатель из параметра.
т.е. в строках 16 и 19 у тебя не копирование?
короче вот, наверное, ближе к тому, как я себе представлял RVO http://paste.ubuntu.com/994024/
f1 — это функция, которую должен оптимизировать компилятор. f2 — то, как я себе представлял, что он это сделает. таки да, в первом случае одно копирование имеет место быть, во втором — ни одного. если я мудак и это вообще бред — прошу объяснить.
что тебе объяснить? что ты мудак? это следует из того что поведение компилятора отличается в лучшую сторону от того что ты от него ожидал. ну и из того что ты два copy c'tor'а написал
не понял. а почему в лучшую когда как раз в худшую от того, что я от него ожидал?
потому что твоё трактование не предусматривает возврат стэк-поинтера к исходному состоянию после выхода из функции
еще раз. ты считаешь, что здесь отсутствует RVO? http://paste.ubuntu.com/994058/
1.
ты считаешь этот код эквивалентным исходному?
В моих экспериментах RVO умирало при наличии более одного return'а. Даже в коде вида
Foo foo;
if (shit)
return foo;
foo.doSmth ();
return foo;
Сносит компилеру башню.
Значит, ты не понимаешь, как работает (N)RVO.
ну короче хоть мне и непонятно еще почему именно невозможно оптимизировать иначе, но я понял, что при NRVO нужно как минимум возвращать "the same named object". про этом это не исключает возможность использоваться много return'ов, при этом имея RVO ни разу.
зачем мне его считать эквивалентным исходному? в нём есть много ретурнов, RVO, и отсутствуют причины посмеяться.
про невозможность оптимизации NRVO при разных named object'ах теперь мне понятно (хотя если эти named object'ы используются в непересекающихся ветвях возврата, то вполне можно было бы и оптимизировать, просто видимо сложно дохуя)