Out params против NRVO при наличии кодов ошибок - PullRequest
0 голосов
/ 27 мая 2018

У нас есть кодовая база, которая широко использует params, потому что каждая функция может завершиться с ошибкой enum.Это становится очень запутанным, и код иногда не читается.

Я хочу устранить этот шаблон и предложить более современный подход.

Цель состоит в том, чтобы преобразовать:

error_t fn(param_t *out) {  
    //filling 'out'
}
param_t param;
error_t err = fn(&param);

в нечто вроде:

std::expected<error_t, param_t> fn() {
    param_t ret;
    //filling 'ret'
    return ret;
}
auto& [err, param] = fn();

Следующие вопросы, чтобы убедить себя и других, это изменение к лучшему:

  1. Я знаю, что на стандартном уровне,NRVO не является обязательным (в отличие от RVO в c ++ 17), но практически есть шанс, что это не произойдет ни в одном из основных компиляторов?
  2. Есть ли преимущества использования параметров вместо NRVO?
  3. Если предположить, что произойдет NRVO, произойдет ли существенное изменение в сгенерированной сборке (при условии, что оптимизированная реализация expected [возможно, с логическим значением, представляющим, полностью ли произошла ошибка])?

1 Ответ

0 голосов
/ 28 мая 2018

Прежде всего, несколько предположений:

  1. Мы смотрим на функции, которые не являются встроенными.В этом случае почти гарантировано, что он будет абсолютно эквивалентен.

  2. Мы собираемся предположить, что сайты вызова функции действительно проверяют состояние ошибки перед использованием возвращенного значения.

  3. Мы будем предполагать, что возвращаемое значение не было предварительно инициализировано с частичными данными.

  4. Мы собираемся предположить, что мы толькозаботьтесь об оптимизированном коде здесь.

Это устанавливается:

Я знаю, что на стандартном уровне NRVO не является обязательным (в отличие от RVO в c ++17) но практически есть ли вероятность, что это не произойдет ни в одном из основных компиляторов?

Предполагается, что NRVO выполняется на данном этапе, это безопасная ставка.Я уверен, что кто-то может придумать надуманную ситуацию, когда этого не произойдет, но я в целом уверен, что почти во всех случаях использования NRVO выполняется на современных современных компиляторах.

При этомЯ бы никогда не стал полагаться на это поведение для программы правильность .То есть я бы не стал создавать странный конструктор копирования с побочными эффектами, предполагая, что он не вызывается из-за NRVO.

Есть ли преимущества использования параметров вместо NRVO?

В общем, нет, но, как и все в C ++, существуют крайние сценарии, в которых он может возникнуть.Явные схемы памяти для максимизации когерентности кэша были бы хорошим вариантом использования для «возврата по указателю».

Если предположить, что произойдет NRVO, произойдет ли существенное изменение в сгенерированной сборке (при условии оптимизации ожидаемой реализации [возможно, с логическим значением, представляющим, исчезла ли ошибка полностью]]?

Этот вопрос не имеет для меня особого смысла.expected<> ведет себя намного больше как variant<>, чем tuple<>, поэтому «логическое представление, означающее, что ошибка полностью исчезла», на самом деле не имеет смысла.

При этом, я думаю, что мыможно использовать std :: option для оценки:

https://godbolt.org/g/XpqLLG

Это "другое", но не обязательно лучше или хуже, на мой взгляд.

...