Talking about static one of the immortal variables

In the process of learning compilation, I realized something, so I wrote down my thoughts and thoughts for future reference.

 

First, let me talk about my understanding of this keyword. Static literally means static, static, unchanging, etc., so after being modified by it, it should also have such characteristics. Facts have proved that this is indeed the case. Using this feature can easily achieve some effects to be achieved in some programming practices. And what is the principle behind its existence? Speaking of this, I have to say that learning the underlying things is a little better, that is, being able to understand the principles. For a person like me who likes to know the truth, it is really attractive.

 

Storage angle:

In my recent assembly study, I learned that there are (but not only) 3 different areas in memory, namely: static storage area, heap and stack . Then they have different functions, and the static storage area is closely related to the static we are going to talk about this time.

We all know that a program needs to be loaded into memory before it can work properly. Have you ever thought about how the program is loaded into memory? And, what exactly is a program? As far as I understand it now, from the perspective of storage, programs are variables and functions. So, loading a program into memory means loading variables and functions into memory. So the question is, what are the variables here? All right. . In fact, any kind of variable is possible, I am most concerned about global variables and static variables (variables modified by static ) .

Because these two kinds of variables are to be placed in the static storage area of ​​the memory (yes, although the variables are all variables, the storage location is very different). Therefore, from a storage point of view, global variables and static variables are stored in the same place, and these two variables (the space occupied) are still hard-coded in the generated target executable file (for compiled languages) ).

I deduce:

1. The global variable is easy to understand, it must exist before any function, so it cannot be in the stack; and the heap variable must also be applied from the function, so if there is no function, it is stored in the global static storage area. Variables can only be provided by the target executable.

2. The static variable still exists after the function is executed and popped from the stack, so it is definitely not on the stack, and it is not dynamically applied, so it is not on the heap. From a storage perspective, its existence In fact, it has nothing to do with functions. So to load it can only come from the target executable.

Therefore, from a storage point of view, static variables are no different from global variables.

 

Logical angle:

There are two concepts to explain here, scope and lifetime .

The scope of a variable is the scope in which the variable can be accessed; and the lifetime of a variable is the period or time when I can access the variable.

So there are at least four combinations: 1. Globally accessible + local (in-function) lifetime 2. Globally accessible + global lifetime 3. Locally accessible + local lifetime 4. Locally accessible + global lifetime

The first possibility is simply a heaven-defying existence. . . It is impossible for a single-threaded program to run two functions at the same time, so this approach is meaningless. So that possibility doesn't exist at all.

The second possibility is global variables.

The third possibility is stack variables, which are local variables of functions.

And the fourth possibility is our highlight today, the static variable modified by static. (Actually, I thought to myself that heap variables can also achieve this effect in a very awkward operation, but it is not a conventional way)

 

Global lifetime is natural for global variables, but what does it mean for variables inside a function whose scope is local? This means that the value of the variable still exists after the function is popped from the stack after the end of the function .

This is the semantics of static - invariant, here the invariant refers to the constant state of the variable's existence. Haha, in fact, it can also be called "immortal variable".

Then some people may ask: what is the use of this? Of course it works, and one of the effects I am most interested in is: functions can store things. Functions are finally not so "dynamic" anymore, they are starting to be a bit "static".

For example, if I want to fetch characters one by one from a string, by using the static modifier, I can gracefully fetch a direct fetch every time a function is called. In C language, I can write it like the following.

 1 #include <stdio.h>
 2 
 3 char getChar(char *str){
 4     static int index = 0;
 5     char result = str[index];
 6     index++;
 7     
 8     return result;
 9 }
10 
11 int main(int argc, char const *argv[]){    
12     char *str = "Hello World!";
13 
14     char c;
15     while( (c=getChar(str)) != '\0' ){
16         putchar(c);
17     }
18 
19     return 0;
20 }

 

One of the advantages of this is that I can do what I want without destroying the original string and it is very convenient to use a separate function.

 

The global lifetime is what they have in common, and the difference lies in the difference in scope , which is also the role of static. Global variables can be accessed in all functions, which will cause security problems, so that when using this variable, it cannot be ensured that its value is only controlled by this function. This is called poor encapsulation . The static modifier can solve this problem. Since the variable modified by it is a local variable of the function, its scope is only within this function, so we can safely conclude that the value of this variable is only controlled by this function. .

 

In languages ​​like Java, it is not allowed to use static to modify local scope variables. I think it may be because there are other ways to express similar semantics, although not exactly the same. And when it comes to object-oriented programming, we can completely think about the problem with another way of thinking, so such a function design method is not so necessary. In Java, the meaning of static is very different from that in C language. We have only talked about the semantics of "immortal variables", which Java does not have, but it has other meanings.

 

To be continued...

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325110491&siteId=291194637