область видимости переменных - PullRequest
3 голосов
/ 03 марта 2011

Почему локальные переменные используют стек в C / C ++?

Ответы [ 7 ]

6 голосов
/ 03 марта 2011

Технически, C не использует стек. Если вы посмотрите на C99 стандарт , вы не найдете ссылки на стек. Это, вероятно, то же самое для стандарта C ++, хотя я его не проверял.

Стеки - это просто детали реализации, используемые большинством компиляторов для реализации семантики автоматического хранения C.

2 голосов
/ 03 марта 2011

Вопрос, который вы на самом деле задаете: «Почему компиляторы C и C ++ используют аппаратный стек для хранения переменных с автоматическим экстентом?»

Как уже упоминалось, ни в определениях языка C, ни C ++ явно не сказано, что переменные должны храниться в стеке.Они просто определяют поведение переменных с различной продолжительностью хранения:

6.2.4 Продолжительность хранения объектов

1 Объект имеет длительность хранения , определяющая его срок службы.Существует три срока хранения: статический, автоматический и распределенный.Выделенное хранилище описано в 7.20.3.

2 время жизни объекта - это часть выполнения программы, в течение которой хранилище гарантированно будет зарезервировано для него.Объект существует, имеет постоянный адрес , 25) и сохраняет свое последнее сохраненное значение в течение всего срока его жизни. 26) Если объект упоминается вне его времени жизни, поведениене определено.Значение указателя становится неопределенным, когда объект, на который он указывает, достигает конца своего времени жизни.

3 Объект, идентификатор которого объявлен с внешней или внутренней связью или со спецификатором класса хранения static, имеет статическая продолжительность хранения .Его время жизни - полное выполнение программы, и его сохраненное значение инициализируется только один раз, до запуска программы.

4 Объект, идентификатор которого объявлен без связи и без спецификатора класса хранения static, имеет длительность автоматического хранения .

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

Стандарт языка C, черновик n1256 .

Нет сомнений в том, что параграф 5 был написан с учетом аппаратных стеков, но есть чудные архитектуры, которые не используютаппаратный стек, по крайней мере, не так, как в x86.Аппаратный стек просто делает поведение, указанное в параграфе 5, простым в реализации.

2 голосов
/ 03 марта 2011

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

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

В кучах есть еще один слой косвенности, так как вам придется идти от Стек -> куча, прежде чем вы получите правильный объект. Также стек является локальным для каждый поток и является по своей природе потокобезопасным, где куча является бесплатной для всех память

1 голос
/ 03 марта 2011

Это зависит от реализации, где хранятся переменные.Некоторые компьютеры могут даже не иметь «стека»: D

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

0 голосов
/ 04 марта 2011

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

Когда происходит переход, локальные переменные нажимаются и переход выполняется. При возврате в область действия локальные переменные выталкиваются.

0 голосов
/ 03 марта 2011

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

0 голосов
/ 03 марта 2011

Локальные переменные являются локальными для кадров в стеке вызовов.

Использование стека позволяет рекурсию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...