也许我错过了一些明显的东西,但是在运行期间,当包含变量的函数被调用时,局部变量会被置于堆栈中。
因此,当编译器逐步执行我们的源代码时,它会将函数的操作放在.text段中,但是变量在编译时放在哪里,这样它们就可以在运行时放到堆栈中?感谢
答案 0 :(得分:7)
在编译时,局部变量不会放在任何地方。
编译器生成的代码在运行时执行时会在堆栈上分配空间(通常可以使用其他方案)。编译器记录有关每个变量的信息(名称,类型,大小,相对于堆栈指针的偏移量等),并使用该信息生成创建,访问和最终解除分配变量的代码。
技术题外话:C没有“本地”和“全局”变量,或者至少语言标准不使用这些术语。对象具有生存期(存储持续时间),这是执行期间存在的时间跨度。或多或少独立地,对象的名称具有范围,这是名称可见的程序文本区域。在函数内声明的变量具有块范围。默认情况下它具有自动存储持续时间(意味着它仅在包含块执行时存在),但如果使用static
定义静态存储持续时间关键字或,如果它是在任何函数之外定义的。 “本地”static
变量将以与“全局”变量相同的方式存储,这与“本地”自动变量的存储方式不同。
答案 1 :(得分:1)
关于您的上述comment:
我认为您要问"问:编译器如何知道如何将源级构造(例如int x
)映射到运行时位置(例如{ {1}})。
是的,symbol tables扮演着重要角色,因为编译器会解析源并生成二进制对象文件。
从以上链接:
符号表是由其创建和维护的重要数据结构 编译器,以便存储有关发生的信息 各种实体,如变量名,函数名,对象, 类,接口等。分析表使用符号表 以及编译器的综合部分。
符号表可以根据具体情况提供以下用途 掌握语言:
以结构化形式存储所有实体的名称。
验证是否已声明变量。
要实现类型检查,通过验证源代码中的赋值和表达式在语义上是正确的。
确定名称的范围(范围解析)。
但是生成和维护符号表只是编译器工作的一部分。以下是整个过程的一些很好的概述:
答案 2 :(得分:0)
C和C ++都没有规定编译器在哪里存储本地(或全局)变量。
根据编译器的不同,本地变量可能存储在堆栈,CPU寄存器,其他内容或根本不存储。
答案 3 :(得分:0)
局部变量在运行时进行处理,但是全局变量在编译时进行,因为它们的范围是预定义的。全局变量存储在进程内存的数据段中,而局部变量存储在堆栈段中。
可以通过以下代码进行交叉验证:
int a= 0;
int main()
{
int b =0 ;
}
After compiling:
.file "test4.c"
.globl a
.bss
.align 4
.type a, @object
.size a, 4
a:
.zero 4
.text
.globl main
.type main, @function
~