2012-02-12 2 views
1

Пусть это стек вызовов моей программы в определенной точке:Как обычно решаются переменные с одинаковым именем?

| b = 2  | 
| c = 3  | <- function f2 
| return address | 
| function args | 
|  ...  | 
| c = 10  | <- function f1 
|  ...  | 

f1()f2() звонки.

При указании переменной c, как это разрешено? Является ли стек поиска линейно сверху вниз, чтобы найти первую переменную с именем c в области видимости или есть какой-то другой механизм, который позаботится об этом более эффективно?

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

+1

Стек не «обыскан», компилятор знает, сколько переменных существует, поэтому функция заканчивается тем, что 5-я локальная переменная находится на расстоянии 48 байт от указателя стека. – Kos

+1

«Переосмысление этого» приходит на ум. Не путайте * язык * с * реализацией *. Язык точно определяет, как ведет себя ваш код, и он это сделает. –

+0

Когда ваш код скомпилирован, любое использование имени переменной заменяется адресом относительно текущего указателя кадра стека. Поиск не требуется. –

ответ

2

В C++ во время выполнения переменные не имеют имен. Имена переменных доступны только для удобства программиста. Переменные имеют область действия в коде, они не имеют области в стеке.

Таким образом, стек не просматривается во время выполнения. Во время компиляции имя переменной преобразуется в адрес памяти.

+0

Если память выделяется только во время выполнения, как получить адрес памяти в compiletime? – Lazer

+0

Я не вижу связи между моим ответом и вашим последующим вопросом, хотя сам по себе интересен. –

1

Компилятор (C или C++) имеет сложную задачу организации каждого кадра вызова.

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

Данное местоположение в кадре вызова может быть (и обычно является, когда оптимизатор компилятора) используется для нескольких целей.

Некоторые локальные переменные не имеют счетных частей в кадре вызова: они существуют только в регистрах. Другие иногда разливаются. Хороший register allocator изо всех сил пытается избежать проливания.

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

Если вы хотите знать, и знать немного о вашем наборе команд процессора x86, вы можете попробовать закодировать крошечное C++ файл tiny.cc и скомпилировать его с g++ -Wall -fverbose-asm -O -S tiny.cc затем посмотреть в генерируемый tiny.s с, например, редактор вроде gedit или emacs или пейджер, например less.

1

Ссылки разрешаются областью действия, основанной на том, где переменная ОПРЕДЕЛЕНА, а не там, где она назначена. Так как в вашем примере вы не показываете ОПРЕДЕЛЕНИЯ, это невозможно сказать.

В языках C не существует вложенных процедур (в некоторых из них игнорируется проблема «thunks»), поэтому стек, по сути, не выполняется. Тем не менее, вы можете иметь в рамках одной процедуры статическую область, вложенную с символами {}, а затем самый внутренний охват (относительно точки отсчета) «выигрывает». В противном случае это область действия процедуры, класс scope, а затем статическая/глобальная область.

Смежные вопросы