简体   繁体   English

C中的static变量如何持久化到memory中?

[英]How do static variables in C persist in memory?

We all know the common example to how static variable work - a static variable is declared inside a function with some value (let's say 5), the function adds 1 to it, and in the next call to that function the variable will have the modified value (6 in my example).我们都知道 static 变量如何工作的常见示例 - 在 function 中声明了一个 static 变量,其中包含一些值(假设为 5),function 将其加 1,并且在下一次调用该 function 时,该变量将被修改值(在我的示例中为 6)。

How does that happen behind the scene?这是如何在幕后发生的? What makes the function ignore the variable declaration after the first call?是什么让 function 在第一次调用后忽略变量声明? How does the value persist in memory, given the stack frame of the function is "destroyed" after its call has finished?鉴于 function 的堆栈帧在其调用完成后被“销毁”,该值如何保留在 memory 中?

The variable isn't stored in the stack frame, it's stored in the same memory used for global variables.该变量未存储在堆栈帧中,它存储在用于全局变量的相同 memory 中。 The only difference is that the scope of the variable name is the function where the variable is declared.唯一不同的是变量名的scope是声明变量的function。

static variables and other variables with static storage duration are stored in special segments outside the stack. static变量和其他具有static个存储期的变量存储在栈外的特殊段中。 Generally, the C standard doesn't mention how this is done other than that static storage duration variables are initialized before main() is called.通常,C 标准没有提及这是如何完成的,只是在调用 main() 之前初始化了 static 存储持续时间变量。 However, the vast majority of real-world computers work as described below:然而,现实世界中绝大多数计算机的工作方式如下:

If you initialize a static storage duration variable with a value, then most systems store it in a segment called .data .如果您使用一个值初始化 static 存储持续时间变量,那么大多数系统会将其存储在名为.data的段中。 If you don't initialize it, or explicitly initialize it to zero, it gets stored in another segment called .bss where everything is zero-initialized.如果你不初始化它,或者明确地将它初始化为零,它会存储在另一个名为.bss的段中,其中所有内容都被零初始化。

The tricky part to understand is that when we write code such as this:难以理解的部分是,当我们编写如下代码时:

void func (void)
{
  static int foo = 5;   // will get stored in .data
  ...

Then the line containing the initialization is not executed the first time the function is entered (as often taught in beginner classes) - it is not executed inside the function at all and it is always ignored during function execution.然后包含初始化的行在第一次输入 function 时不会执行(在初学者课程中经常讲授) - 它根本不会在 function 内部执行,并且在 function 执行期间始终被忽略。

Before main() is even called, the "C run-time libraries" (often called CRT) run various start-up code.在调用 main() 之前,“C 运行时库”(通常称为 CRT)会运行各种启动代码。 This includes copying down values into .data and .bss .这包括将值复制到.data.bss中。 So the above line is actually executed before your program even starts.所以上面这行实际上是在你的程序开始之前执行的。

So by the time func() is called for the first time, foo is already initialized.所以当func()第一次被调用时, foo已经被初始化了。 Any other changes to foo inside the function will happen in run-time, as with any other variable.与任何其他变量一样,function 中foo的任何其他更改都将在运行时发生。

This example illustrates the various memory regions of a program.此示例说明了程序的各个 memory 区域。 What gets allocated on the stack and the heap?堆栈和堆上分配了什么? gives a more generic explanation.给出了更通用的解释。

Quoting C11 , chapter 6.2.4引用C11 ,第 6.2.4 章

An object whose identifier is declared [...] with the storage-class specifier static , has static storage duration.一个 object 其标识符声明为 [...] 存储类说明符static ,具有 static 存储持续时间。 Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.它的生命周期是程序的整个执行过程,它的存储值只在程序启动之前初始化一次。

In a typical implementation, the objects with static storage duration are stored either in the data segment or the BSS (based on whether initialized or not).在典型的实现中,具有 static 存储持续时间的对象存储在数据段或 BSS 中(根据是否已初始化)。 So every function call does not create a new variable in the stack of the called function, as you might have expected.因此,每个 function 调用都不会像您预期的那样在被调用的 function 的堆栈中创建一个新变量。 There's a single instance of the variable in memory which is accessed for each iteration. memory 中有一个变量实例,每次迭代都会访问它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM