Размещение объектов в стеке, традиционный подход
Возникает вопрос: а почему бы функциям не возвращать объекты в стек?
В «машинный», наверное, не получится, но в программный — вполне.
Программный стек требует бо́льших накладных расходов, но давайте сначала разберёмся,
чего мы хотим, а потом подумаем, как это сделать.
Разбираться начнём с рассмотрения механизма передачи параметров и возврата значений в функциях,
и почему это препятствует возврату значений переменной длины.
Рассмотрим пример (в этом и всех последующих примерах рассмотрен вариант для C++, для x86, в режиме 32 бита):
f2(<параметры f2>) { // определение f2
<локальные переменные f2>
...
}
f1(<параметры f1>) { // определение f1
<локальные переменные f1>
f2(<параметры f2>); // вызов f2
}
f1(<параметры f1>); // вызов f1
Память в стеке при вызове этих функций будет распределена так:
Если стоит задача передать в функцию f1 из функции f2 объект,
чья длина становится известной только при вызове f2, то как это сделать?
Первый способ: записать его в стек ниже локальных объектов функции f2.
Это плохая идея: весь фрагмент стека, принадлежащий функции f2 станет бесполезным пространством.
Использовать его больше нельзя, т.к. при вызове других функций локальные данные этих функций могут затереть результат работы f2.
Второй способ: записать его в стек ниже локальных объектов функции f1.
В этом случае будут затёрт фрагмент стека функции f2, которая, скорее всего, утеряет даже адрес возврата.
Однако, отметим себе такую возможность: в дальнейшем мы к ней вернёмся. Читаем далее следующую статью:
Размещение объектов переменной длины с использованием множества стеков.
Почитайте ещё:
Опубликовано: 2014.07.27, последняя правка: 2018.10.29 16:03
Отзывы
✅ 2016/08/09 04:50, rst256 #0
Задача сформулирована слишком узко, в реальности в большинстве случаев будет вот так: f2(<параметры f2>) { ... } f1(<параметры f1>) { ... f2(<параметры f2>); } f0(<параметры f1>) { ... f2(<параметры f2>); } some(const <параметры some>); some2(const <параметры some2>); foo(<параметры foo>) { x=f2(<параметры f2>); some(x); return x; } bar(<параметры bar>) { some2(foo(<параметры foo>)); }
f0(<параметры f0>); f1(<параметры f1>); x=foo(<параметры foo>); bar(<параметры bar>); Вот почему никто ИМЕННО ТАКИМ способом значения не возвращает. Какой смысл делать возможность получить значение в локальную область вызывающей функции, если надо получить значение в "туда, куда надо в данном случае"? Например, напишу я таким образом аналог функции strcat. И кому будет такой strcat нужен? Добавить свой отзыв
Написать автору можно на электронную почту mail(аt)compiler.su
|