T.J*_*.J. 8 c c++ variables memory-management
以下陈述是什么意思?
本地和动态分配的变量具有编译源文件时编译器不知道的地址
我曾经认为局部变量在编译时被分配地址,但是当它超出范围然后在函数调用期间再次进入范围时,该地址可以改变.但是上面的声明说编译器不知道局部变量的添加. 然后如何分配局部变量?为什么在编译时可以知道全局变量的地址?
另外,您能否提供一个很好的链接来阅读如何分配局部变量和其他变量?
提前致谢!
tem*_*def 13
上面的引用是正确的 - 编译器通常在编译时不知道局部变量的地址.也就是说,编译器可能知道从局部变量所在的堆栈帧的基础偏移,但是根据调用堆栈的深度,可能会在运行时转换为不同的地址.作为一个例子,考虑这个递归代码(顺便说一句,它不是任何好的代码!):
int Factorial(int num) {
int result;
if (num == 0)
result = 1;
else
result = num * Factorial(num - 1);
return result;
}
Run Code Online (Sandbox Code Playgroud)
根据参数的不同num,此代码最终可能会进行多次递归调用,因此result内存中会有多个副本,每个副本都包含不同的值.因此,编译器无法知道它们的全部内容.但是,每个实例result可能会从包含每个Factorial调用的堆栈帧的基础偏移相同的数量,但理论上编译器可能会执行其他操作,例如优化此代码,以便只有一个副本result.
通常,编译器通过维护堆栈帧的模型并跟踪堆栈帧中下一个空闲位置的位置来分配局部变量.这样,可以相对于堆栈帧的开始分配局部变量,并且当调用函数时,可以使用相对地址,结合堆栈地址,在特定堆栈帧中查找该变量的位置.
另一方面,全局变量可以在编译时知道它们的地址.它们与本地人的不同之处主要在于程序中始终存在一个全局变量的副本.局部变量可能存在0次或更多次,具体取决于执行的方式.由于存在一个唯一的全局副本,编译器可以对其进行硬编码.
至于进一步阅读,如果你想对编译器如何布局变量进行相当深入的处理,你可能想要获取Aho,Lam 的编译器:原理,技术和工具,第二版的副本, Sethi和Ullman.虽然本书的大部分内容涉及其他编译器构造技术,但本书的大部分内容专门用于实现代码生成和可用于改进生成代码的优化.
希望这可以帮助!