GNU C(ネストされた関数)のアクティベーションレコード
-
26-10-2019 - |
質問
GNU Cでは、結果は13です。静的リンクが使用されているため。
それ以外の場合、動的リンクを使用すると、結果は16になります。
#include <stdio.h>
int h(){
int x = 1;
int g(int z){
return z + x; <------------------ P
}
int f(int y){
int x = y + 1;
return g(x * y);
}
return f(3);
}
int main(){
int a = h();
printf("%d\n", a);
}
Pポイントでは、アクティベーションレコードはです
z = 12
x = 4
y = 3
fとコードへのポインターf
gとコードgへのポインター
x = 1
hとコードへのポインターh
a
メインおよびポインターコードメイン
そうですか?
ただし、関数Gが戻った場合、どうですか?
Gの活性化と可変Zの活性化は削除されます。
その後、スタックフレームでは、穴が見えます。穴が本当に表示されますか?
インラインブロックによると、関数hでは
可変Xは最も外側のブロックです。 (これは、関数g 'ブロックが可変xのブロックにネストされていることを意味します)次の外側ブロックは関数g、次の関数f ...次に、関数fの静的リンクポイントを関数Gのフレームポインターにしますか?または機能Hのフレームポインター?関数Gの静的リンクはどうですか?
解決
ポイントPでは、スタックに4つのアクティベーションレコードがあります。
Gのアクティベーションレコード:
- fにアドレスを返します
- H Activation Recordへの静的リンク
- z =
12
Fのアクティベーションレコード:
- x =
4
- hにアドレスを返します
- H Activation Recordへの静的リンク
- y =
3
Hのアクティベーションレコード:
- x =
1
- メインへのアドレスを返します
メインのアクティベーションレコード:
- a = 未定義
- OSにアドレスを返します
ネストされた関数の各アクティベーションレコードには、関数が呼び出され、アクティベーションレコードが作成されるときに設定される字句的に囲まれたアクティベーションレコード(両方の場合のH)へのリンクが含まれています。ポイントPでは、コードはxの値を見つけるためのリンクを再確認し、そのようなリンクを調べることは、関数が他の関数のアクティベーションレコードを見る唯一の時間です。
他のヒント
ポイントPで、 x
を参照することができます x
で定義されています h()
;それは、しか参照できませんでした x
の g()
それ自体が中にネストされている場合 g()
.