假设这是我的程序在特定点的调用堆栈:
| b = 2 |
| c = 3 | <- function f2
| return address |
| function args |
| ... |
| c = 10 | <- function f1
| ... |
f1()
来电f2()
。
当引用变量c
时,它是如何解决的?是否自上而下线性搜索堆栈以查找范围中名为c
的第一个变量,或者是否有一些变量其他机制可以更有效地处理这个问题吗?
如果每次都搜索堆栈,那么当引用不存在的变量d
时,它不会成为开销,因为堆栈将一直被搜索以找出范围内没有这样的变量?
答案 0 :(得分:2)
在C ++中,在运行时期间变量没有名称。变量名只是为了方便程序员。变量在代码中具有范围,它们在堆栈中没有范围。
因此在运行时不会搜索堆栈。在编译期间,变量名称将转换为内存地址。
答案 1 :(得分:1)
(C或C ++)编译器具有组织每个调用帧的困难任务。
在发布与源代码中的局部变量相关的机器代码时,它会将局部变量的访问和修改转换为合适的指令(通常使用堆栈或帧指针作为基础)。
调用帧中的给定位置可以(通常是在编译器优化时)用于多种用途。
一些局部变量在调用帧中没有计数器部分:它们只存在于寄存器中。其他人有时会泄漏。一个好register allocator努力避免溢出。
调用帧布局,寄存器分配,指令调度是优化编译器的难题。
如果您很好奇并且对x86处理器指令集有所了解,您可能会尝试编写一个小的C ++文件tiny.cc
并使用g++ -Wall -fverbose-asm -O -S tiny.cc
进行编译,然后查看生成的{{1}用例如像tiny.s
或gedit
这样的编辑器或像emacs
这样的寻呼机。
答案 2 :(得分:1)
引用由范围解决,基于变量DEFINED的位置,而不是它的ASSIGNED。因为在你的例子中你没有显示任何定义,所以不可能说出来。
在基于C的语言中,没有嵌套过程(忽略其中一些“thunks”的问题),因此不会搜索堆栈本身。但是,您可以在单个过程中使用{}
字符嵌套静态范围,然后在最内部范围(相对于参考点)“获胜”。否则,它是过程范围,类范围,然后是静态/全局范围。