и при критических обстоятельствах разрушаться,
Программа может либо полностью игнорировать эту возможность и при критических обстоятельствах разрушаться, либо проверять размер стека перед каждым вызовом процедуры, что может быть накладно. Компромиссное решение состоит в том, чтобы периодически проверять размер стека и предпринимать некоторые действия, если он стал меньше некоторого предельного значения, скажем 1000 слов.
7.7. Еще о стековой архитектуре
Доступ к переменным на промежуточных уровнях
Мы обсудили, как можно эффективно обращаться к локальным переменным по фиксированным смещениям от указателя дна, указывающего на запись активации. К глобальным данным, т. е. данным, объявленным в главной программе, также можно обращаться эффективно. Это легко увидеть, если рассматривать глобальные данные как локальные для главной процедуры. Память для глобальных данных распределяется при входе в главную процедуру, т. е. в начале программы. Так как их размещение известно на этапе компиляции, точнее, при компоновке, то действительный адрес каждого элемента известен или непосредственно, или как смещение от фиксированной позиции. На практике глобальные данные обычно распределяются независимо (см. раздел 8.3), но в любом случае адреса фиксированы.
Труднее обратиться к переменным на промежуточных уровнях вложения.
procedure Main is
G: Integer,
procedure Proc_1 is
L1: Integer;
Ada |
L2: Integer;
begin L2 := L1 + G; end Proc_2;
procedure Proc_3 is
L3: Integer;
begin L3 := L1 + G; Proc_2; end Proc_3;
begin -- Proc_1
Proc_3;
end Proc_1;
begin — Main
Proc_1;
end Main;
Мы видели, что доступ к локальной переменной L3 и глобальной переменной G является простым и эффективным, но как можно обращаться к L1 в Ргос_3? Ответ прост: значение указателя дна сохраняется при входе в процедуру и используется как указатель на запись активации объемлющей процедуры Ргос_1.