Приведенная выше цитата верна - компилятор обычно не знает адреса локальных переменных во время компиляции.Тем не менее, компилятор, вероятно, знает смещение от основания фрейма стека, в котором будет расположена локальная переменная, но в зависимости от глубины стека вызовов, которое может преобразоваться в другой адрес во время выполнения.В качестве примера рассмотрим этот рекурсивный код (который, кстати, вовсе не является хорошим кодом!):
int Factorial(int num) {
int result;
if (num == 0)
result = 1;
else
result = num * Factorial(num - 1);
return result;
}
В зависимости от параметра num
этот код может закончить создание нескольких рекурсивныхвызовов, поэтому в памяти будет несколько копий result
, каждая из которых будет иметь разное значение.Следовательно, компилятор не может знать, куда они все пойдут.Однако каждый экземпляр result
, вероятно, будет смещен на одну и ту же величину от основания фрейма стека, содержащего каждый вызов Factorial
, хотя в теории компилятор может делать другие вещи, такие как оптимизация этого кода, чтобы была только одна копияresult
.
Обычно компиляторы распределяют локальные переменные, поддерживая модель кадра стека и отслеживая, где находится следующее свободное место в кадре стека.Таким образом, локальные переменные могут быть размещены относительно начала кадра стека, и когда функция вызывается, этот относительный адрес может использоваться вместе с адресом стека для поиска местоположения этой переменной в конкретном кадре стека..
С другой стороны, глобальные переменные могут иметь свои адреса, известные во время компиляции.Они отличаются от местных в первую очередь тем, что в программе всегда есть одна копия глобальной переменной.Локальные переменные могут существовать 0 или более раз в зависимости от того, как выполняется выполнение.В результате того, что существует одна уникальная копия глобала, компилятор может жестко закодировать адрес для него.
Что касается дальнейшего чтения, если вы хотите довольно углубленное рассмотрение того, каккомпилятор может размещать переменные, вы можете выбрать копию Компиляторы: принципы, методы и инструменты, второе издание от Aho, Lam, Sethi и Ullman.Хотя большая часть этой книги касается других методов конструирования компиляторов, большой раздел книги посвящен реализации генерации кода и оптимизации, которая может быть использована для улучшения сгенерированного кода.
Надеюсь, это поможет!