Подтвердить что ты не робот

Как функции С++ возвращают большой объект или структуру?

Я прочитал в Computer Systems перспективу программиста, что при программировании в ассемблере в соглашении относительно протокола вызывающего абонента указано, что возвращаемое значение функции должны храниться в регистре eax (или аналоговом rax, в 64-битном компьютере).

Я предполагаю, что это то, что автоматически происходит "за кулисами" при программировании на C, то есть компилятор C "знает", чтобы использовать регистр eax для возвращаемых значений функций.

Но что происходит в С++, когда возвращаемое значение является большим объектом, который не вписывается в 32-разрядный регистр eax или 64-бит rax? Очевидно, вы не можете передать это с помощью стека, так как компилятор обрабатывает операцию возврата по значению большого объекта?

Не обращайте внимания на большой объект, как компилятор C обрабатывает возвращаемую стоимость большой структуры?

Сохраняет ли он его во временном пространстве памяти и возвращает его адрес как возвращаемое значение? Если это так, он должен предсказать, сколько вызовов нужно делать с функцией во время выполнения, а иногда это невозможно, не так ли?

4b9b3361

Ответ 1

Очевидно, вы не можете передать это с помощью стека...

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

Это напрямую соответствует тому, как он работает на C и С++. У вас есть оператор return ...;, который копирует некоторое значение в возвращаемый объект. Возвращаемый объект является временным объектом, поэтому вызывающий код должен его хранить где-то с чем-то вроде int value = foo();.

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

Ответ 2

Очевидно, вы не можете передать это, используя стек

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

По существу, функция возвращает данные в части вызывающего элемента кадра стека.

Ответ 3

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