ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
17 апреля
1053842 Топик полностью
fk0, легенда (20.11.2020 00:00, просмотров: 281) ответил teap0t на Я чего-то явно не понимаю. Мы же структуру возвращаем куда-то, т.е. в переменную имеющую такой же тип. Она уже определена и занимает память. Мы не можем обращаться к полям структуры через x = my_func(..).field_1;
Мы структуру возвращаем во временный объект. Но опять же следует разделить, то что как бы понарошку, и что получается на самом деле. Этот временный объект -- он существует только в голове у тебя, компилятор там как-то аллоцирует регистры и куда-то положит лучше тебя, не твоя забота. И этот временный объект живёт до точки с запятой (';'), потом уничтожается. 

Ты можешь его присвоить именованной переменной ( struct S = f() ), или можешь сразу адресовать поля этого объекта ( f().a ). В первом случае дабы оптимизировать лишние перекладывания байтов туда-сюда-обратно компилятор может подогнать адрес var так, -тоб она лежала прямо в месте временного объекта. 0 тактов и всё решено. Но если ты так в цикле будешь делать с двумя структурами, ясно, уже так не получится, пример:


Compiler Explorer


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


То-есть возврат структур по-значению хорошо работает в тривиальных случаях, когда возвращённы значения тут же используются, например. Или когда по крайней мере результат кладётся во вновь продекларированную переменную (а не использованную ранее: тогда можно постоянно заводить на стеке новые временные значения и двигать его вниз). А когда приходится переписывать возвращаемым значением уже ранее существующую переменную (пример с циклом), или когда вершина стека может быть занята другими вычислениями (опять же цикл не позволяет двигать стек вниз) -- случай нетривиальный и возврат структуры по значению не эффективен.

[ZX]