Summary of static usage in C/C ++

Source: Internet
Author: User

This article describes the following content:
1. Role of static in C Language
2. reusability of functions
3. Functions of static in C ++

Static keywords in C

Painful lessons:

Suppose a static bool g_test = false is defined in test. h;

If both test1.c and test2.c contain test. H, test1.c and test2.c generate two g_test copies respectively, and set g_test = true in test1.c, while the value of false in test2.c remains unchanged! Shit !!

I. C program storage space layout

C Programs are always composed of the following parts:

1) body segment-The machine instruction part executed by the CPU; a program has only one copy; read-only to prevent the program from modifying its instruction due to accidents;
2) initialize the data segment (Data Segment)-store all the global variables assigned with the initial value in the program.
3) Non-initialized data segment (BSS segment) -- no global variable is initialized in the program; the kernel initializes this segment to 0.
4) Stack-growth direction: top-down growth; automatic variables and information to be saved for each function call (return address and environment information ).
5) Heap-dynamic storage.

| ----------- |
|
| ----------- |
| Stack |
| ----------- |
|
|/|
|
|
|/|
|
| ----------- |
| Heap |
| ----------- |
| Not initialized |
| ----------- |
| Initialization |
| ----------- |
| Body segment |
| ----------- |

Ii. process-oriented programmingStatic

1. Global static variables
2. Local static variables
3. Static Functions

1. Global static variables

When the keyword static is added before the global variable, the global variable is defined as a Global static variable.

1) location in the memory: static storage area (the static storage area exists throughout the Program)

2) initialization: uninitialized Global static variables will be automatically initialized to 0 by the program (the value of the automatic object is arbitrary unless it is displayed as initialized)

3) Scope: The Global static variable is invisible outside the file that declares it. Accurately speaking, it starts from the definition to the end of the file.

Let's take a look at the program about the scope:
// Teststatic1.c
Void display ();
Extern int N;
Int main ()
{
N = 20;
Printf ("% DN", N );
Display ();
Return 0;
}
 
// Teststatic2.c
Static int N; // defines the Global static variable. It is automatically initialized to 0 and only visible in this file.
Void display ()
{
N ++;
Printf ("% DN", N );
}
 

The file is compiled separately, but the Variable N in teststatic2.c cannot be found during link, resulting in an error.
 
Benefits of defining global static variables:

<1> cannot be accessed by other files. Modify

<2> variables with the same name can be used in other files without conflict.

2. Local static variables

When the keyword static is added before the local variable, the local variable is defined as a local static variable.

1) location in memory: static storage Zone

2) initialization: uninitialized Global static variables will be automatically initialized to 0 by the program (the value of the automatic object is arbitrary unless it is displayed as initialized)

3) scope: the scope is still a local scope. When the function or statement block that defines it ends, the scope ends.

For example, the light sensor in our project is cm36283, and the static variable is used when the ALS value is obtained from the sensor, which is very strange at first,
I thought it was a bug (because it would return a negative value). Take a closer look at the other day.

Static int cm36283_get_als (struct i2c_client * client)
{
Int ret;
Staticint
Als_buf [3];
Static int idx = 0;
Ret = cm36283_read_als (client );
If (Ret>-1)
Ret = lux_calc (RET );
If (Ret> als_max)
Ret = als_max;
If (Ret>-1)
{
Als_buf [idx] = ret;
Idx ++;
}
If (idx = 3)
{
Ret = (als_buf [0] +
Als_buf [1] + als_buf [2])/3;
Idx = 0;
}
Else
Ret =-5;
Return ret;
}

First, this function is called in delay_work. the return value is used to report data to the input subsystem,
This function is called once every MS, but to prevent false triggering (such as mobile phone flip rather than significant changes in ambient light), this function calculates the average value of three times before reporting,
That is, the input subsystem receives one data every Ms. This function is implemented by static local variables als_buf and idx. The data read is saved for the first two times.
Then, a negative value (-5) is returned, which is used to judge whether the data is not reported. The third time the data is read, the average value of three times is obtained, and the average value is returned, so that the data is reported.
Two questions:
1) Why not remove static? -------- Data cannot be saved, and non-static local variable functions will disappear after being called!
2) Setting als_buf and idx as Global static variables can also achieve the same function. Why not? ------- To minimize the scope of the variable, because it is only used in this function.
We may think of global variables most easily if we do not know the role of static local variables.

Summary: When static is used to modify local variables, it changes the storage location of local variables from the original stack to the static storage zone. However, after leaving the scope, the local static variables are not destroyed, but still resident in the memory until the program ends, but we cannot access them any more.

When static is used to modify a global variable, it changes the scope of the global variable (invisible outside the declared file), but does not change its storage location, or in the static storage area.

3. Static Functions

When the keyword static is added before the return type of the function, the function is defined as a static function.

Function definitions and declarations are extern by default, but static functions are only visible in the declared files and cannot be used by other files.

For example:
// Teststatic1.c
Void display ();
Static void staticdis ();
Int main ()
{
Display ();
Staticdis ();
Required urn 0;
}
 
// Teststatic2.c
Void display ()
{
Staticdis ();
Printf ("Display () has been called N ");
}
 
Static void staticdis ()
{
Printf ("staticdis () has been calledn ");
}
 
The file is compiled separately, but the staticdis () function cannot be found during the connection, resulting in an error.
Not compiled yet. vc2003 reports that the static function staticdis in teststatic1.c has been declared but not defined. By imjacob
Benefits of defining static functions:

<1> functions with the same name can be defined in other files without conflict.

<2> static functions cannot be used by other files.
 
The storage specifiers auto, register, extern, and static correspond to two storage periods: Automatic Storage Period and static storage period.
 
Auto and register correspond to the automatic storage period. A variable with an automatic storage period is created when it enters the block where the variable is declared. The variable exists during the block activity and is revoked when it exits the block.

Extern and static are used to describe variables and functions with a static storage period. Local variables declared with static have static storage duration or static range (static extent ). Although its value remains valid between function calls, its name visibility is limited to its local domain. The static local object is initialized for the first time when the program executes the declaration of the object.

Some specific functions can be implemented due to the above features of static variables.

1. Count statistics function

Declare a local variable of the function and set it to the static type as a counter so that the function can be counted every time it is called. This is the best way to count the number of function calls, because this variable is closely related to the function, and the function may be called in multiple different places, therefore, it is difficult to collect statistics from the caller's perspective. The Code is as follows:
 
Void count ();
Int main ()
{
Int I;
For (I = 1; I <= 3; I ++)
Count ();
Return 0;
}
Void count ()
{
Static num = 0;
Num ++;
Printf ("I have been called % d", num, "timesn ");
}

Output result:
I have been called 1 times.
I have been called 2 times.
I have been called 3 times.

Differences between static global variables and static local variables:
All are stored in the static storage area. The only difference is that the scope is different. In order to reduce the coupling between modules, in principle, the scope should be minimized.
This is why the above does not use static global variables!

C-language programs can be viewed as composed of a series of external objects, which may be variables or functions. Internal variables refer to the function parameters and variables defined within the function. External variables are defined outside functions, so they can be used in many functions. Since the C language does not allow defining other functions in a function, the function itself can only be "external ".

C language code is organized in files. In all source files of a source program, an external variable or function can be defined only once in a file, other files can access it through the extern Declaration (the source file defining the external variable or function can also contain the extern Declaration for the external variable ).
Static storage can restrict variables or functions to static storage. If you use static to restrict external variables and functions, You can restrict the scope of the object to the rest of the compiled source file. You can use static to restrict external objects to hide them. Therefore, static variables or functions do not conflict with the same name in other files in the same program. If you use static to limit the internal variable, the variable will have memory from the beginning of the program and will not be allocated and disappear as the function calls and exits.
Benefits of using static functions in C:
Static functions are automatically allocated to a used storage area until they exit the application instance. This avoids the pressure on the stack to exit the stack when calling the function, which is much faster.
The keyword "static" is "static" in Chinese. Therefore, internal functions are also called static functions. However, the meaning of "static" here is not the storage method, but the scope of the function is limited to this file. The advantage of using internal functions is that when different people write different functions, you don't have to worry about whether your own defined functions will have the same name as the functions in other files, because the same name does not matter.
Static semantics in C Language
1. Static variables:
1). Local
A. Static local variables are defined in the function. The lifetime is the entire source program, but the scope is the same as that of automatic variables. They can only be used in the function that defines the variable. After exiting the function, although the variable still exists, it cannot be used.
B. If an initial value is not assigned to a static local variable of the basic type, the system automatically assigns the value 0. If the initial value is not assigned to the automatic variable, the value is not fixed.
2). Global
Global variables are static storage, and static global variables are also static storage. But their scope: the scope of non-static global variables is the entire source program (multiple source files can be used together), while static global variables limit their scope, that is, it is valid only in the source file defining the variable and cannot be used in other source files of the same source program.
2. Static function (also called internal function)
It can only be called by functions in this file, but not by functions in other files of the same program. Different from general non-static functions (external functions)
Static can be used to modify variables or functions in C.
Let's first look at the time when it is used to modify variables. Variables in C can be divided into global data areas, stacks, and stacks. In fact, the stack we usually call is a stack that does not contain a pair. Don't confuse it.
Int;
Main ()
{
Int B;
Int C * = (int *) malloc (sizeof (INT ));
}
A is a global variable, B is a stack variable, and C is a stack variable.
Static modification to the global variable can be considered as limiting that the variable can only be referenced in this file. Some programs are composed of many. c files. Variables can be referenced by each other. However, after static modification, the variable can only be referenced by functions in this file.
Static modification of stack variables can be considered to extend the life cycle of stack variables to the end of program execution. In general, the life cycle of stack variables is managed by OS. During the rollback process, the life of stack variables ends. However, after static modification, the variables are not stored in the stack, but stored together with global variables. At the same time, it cannot be used after the function that defines it is left blank. However, if you call the function that defines it again, it can continue to be used and save the value left after the previous call.
Static Function Modification is similar to global variable modification. It can only be called by functions in this file, but cannot be called by functions in other files of the same program.
Static declared variables have two features in the C language:
1) The variables will be placed in the global storage area of the program, so that the original values can be maintained during the next call. This is the difference between stack variables and heap variables.
2) The variable uses static to notify the compiler that it is only visible within the scope of the variable. This is the difference between it and global variables.
 
Question: static understanding
For static variables, select the correct content for all the following statements:
A. if the global variable is only accessed in a single c file, you can change the variable to a static global variable to reduce the coupling between modules;
B. If the global variable is only accessed by a single function, you can change the variable to the static local variable of the function to reduce the coupling between modules;
C. When designing and using functions that access dynamic global variables, static global variables, and static local variables, you need to consider re-import;
D. The static global variable is too large, which may cause stack overflow.
Answer and analysis:
For A, B: according to the description in the overview section B), we know that a and B are correct.
For C: according to the description in the overview section of this article a), we know that C is correct (the so-called function re-entry problem is described in detail below ).
For D: static variables are placed in the global data zone of the program, rather than allocated in the stack, so it is impossible to cause stack overflow. D is wrong.
Therefore, the answer is A, B, and C.
 
Problem: Non-reentrant Functions
A fatal weakness of a function using static local variables is that it cannot be re-imported! In a multi-threaded environment, functions can be divided into reentrant and non-reentrant functions,
For more information about this concept, see

Reentrant function
I have designed a function such as the next function. I was reminded of a bug during code check because this function cannot be reentrant. Why?
Unsigned int sum_int (unsigned int Base)
{Unsigned int index;

Static unsigned int sum = 0; // note that it is of the static type.
For (Index = 1; index <= base; index ++)
{
Sum + = index;
}
Return sum;
}
Answer and analysis:
The so-called function is reentrant (or predictable), that is, the same output should be generated as long as the input data is the same.
This function is unpredictable because it uses static variables. Because of the characteristics of static variables, such a function is called a function with the "internal memory" function. Therefore, if we need a reentrant function, we must avoid using static variables in the function. The principle of using static variables in this function is that we do not need to use them as much as possible.
It is very easy to change the above function to a reentrant function. As long as the static keyword in the declared sum variable is removed, the variable sum is changed to an auto type variable, A function is a reentrant function.
Of course, in some cases, static variables must be used in functions. For example, when a function returns a pointer type, the address of a static local variable must be used as the return value, if it is of the auto type, an error pointer is returned .????

-----------------------------------

Differences between C and C ++ static functions


The static keyword is a keyword that exists in both C and C ++. It mainly has three usage methods. The first two are only used in C, the third method is used in C ++. (The detailed operations in C and C ++ vary. This document uses C ++ as the standard ).
(1) local static variables
(2) external static variables/functions
(3) static data member/member functions

The following three usage methods and precautions are described respectively.

I. Local static variables

In C/C ++, local variables can be divided into three types: auto, static, and register.
(<C language programming (second edition)> tan haoqiang, pp. 174-175)
Compared with the auto-type (common) local variable, the static local variable has three differences.

1. Different Storage space allocations
The auto type is allocated to the stack and belongs to the dynamic storage class, occupying the dynamic storage space. The function is automatically released after the function call is completed, and the static type is allocated to the static storage area, the program is not released during the entire running period. they have the same scope but different lifetime.

2. Static local variables initialize at the first run of the module and operate only once

3. for local static variables, if no initial value is assigned, the initial value 0 or null characters are automatically assigned during the compilation period, while the initial values of the auto type are uncertain. (except for class objects in C ++, if the class object instance is not initialized, the default constructor is automatically called, regardless of whether the class is static or not)
Features: "Memory" of static local variables and "Global" of lifetime"
The so-called "Memory" refers to the value of the first function call exit when the second function call enters.

Example 1
# Include <iostream>
Using namespace STD;
Void staticlocalvar ()
{
Static int A = 0; // Initialization is performed at runtime. Initialization is not performed for the next call.
Cout <"A =" <A <Endl;
++;
}
Int main ()
{
Staticlocalvar (); // the first call, output a = 0
Staticlocalvar (); // The second call, remembering the value at the first exit, output a = 1
Return 0;
}

Application:
Use "Memory" to record the number of function calls (Example 1)
Improve the problem of "return a pointer/reference to a local object" by using global survival. the problem with the local object is that the function exits and the lifetime ends ,. use static to prolong the lifetime of a variable.

Example 2:
// Ip address to string format
// Used in Ethernet frame and IP header analysis
Const char * iptostr (uint32 ipaddr)
{
Static char strbuff [16]; // static local variable, used to return valid addresses
Const unsigned char * PChIP = (const unsigned char *) & ipaddr;
Sprintf (strbuff, "% u. % u. % u", PChIP [0], PChIP [1], PChIP [2], PChIP [3]);
Return strbuff;
}

Note:
1. "Memory", a very important part of the program running is repeatability, while the "Memory" of static variables damages this repeatability, resulting in different runtime results may be different.
2. global and uniqueness of "Lifetime. the storage space of common local variables is allocated to the stack. Therefore, the allocated space may be different each time a function is called. Static has the global uniqueness feature, all point to the same memory, which causes a very important problem ----Reentrant is not allowed !!!
In this way, pay special attention to this issue in multi-threaded or recursive programming.
(Examples of non-reentrant properties can be found in <effective C ++ (2nd)> (photoprinting) page 103-105)
The following is an example of Program 2, which is used to analyze the security of multiple threads (to facilitate the description, mark the row number)
① Const char * iptostr (uint32 ipaddr)
② {
③ Static char strbuff [16]; // static local variable, used to return valid addresses
④ Const unsigned char * PChIP = (const unsigned char *) & ipaddr;
⑤ Sprintf (strbuff, "% u. % u. % u", PChIP [0], PChIP [1], PChIP [2], PChIP [3]);
⑥ Return strbuff;
7}
Assume that there are two threads a and B that need to call the iptostr () function during runtime, and convert the 32-bit IP address into a string in the 10th notation. now a gets the execution opportunity and runs iptostr (). The input parameter is 0x0b090a0a. After the execution is complete, the returned pointer storage area is: "10.10.9.11". When the execution ends, if the execution permission is lost, the task is scheduled to run in line B. The parameter passed in line B is 0xa8a8c0 and executed to 7. The content in the static storage area is 192.168.168.168. when it is scheduled to execute a again, it continues from 6th to 6th. Due to the global uniqueness of strbuff, the content has been washed out by line B,
The return value is the string 192.168.168.168, which is no longer the string 10.10.9.11.

Ii. External static variables/functions

In C, static has the second meaning: Used to indicate global variables and functions that cannot be accessed by other files. However, to restrict the scope of global variables/functions, add static before a function or variable to make the function a static function. However, the meaning of "static" here is not the storage method, but the scope of the function is limited to this file (so it is also called an internal function ). Note that, whether static or not, external (global) variables are stored in the static storage area and the lifetime is global. at this time, static only applies to the scope, and the scope is limited within this module (file.
The advantage of using internal functions is that when different people write different functions, you don't have to worry about your own defined functions and whether they will have the same name as the functions in other files.

Example 3:
// File1.cpp
Static int Vara;
Int varb;
Extern void FUNA ()
{
......
}
Static void funb ()
{
......
}

// File2.cpp
Extern int varb; // use the global variable defined in file1.cpp
Extern int Vara; // error! Vara is static and cannot be used in other files
Extern vod funa (); // use the function defined in file1.cpp
Extern void funb (); // error! You cannot use the static function in the file1.cpp file.

Iii. static data member/member functions (C ++ exclusive)

C ++ has reused this keyword and given it a third meaning different from the previous one: to indicate variables and functions belonging to a class rather than any specific objects of this class. this is the biggest difference between a function and a common member function and its application. For example, when counting an object of a class, counting the number of instances of the class is generated, you can use static data members. static does not limit the scope or extend the lifetime, but indicates the uniqueness of variables/functions in this class. this is also the meaning of "variables and functions that belong to a class rather than any specific objects of this class. because it is unique for the entire class, it cannot belong to an instance object. (For static data members,
Whether the member function is static or not, there is only one copy in the memory. When calling a common member function, you need to input this pointer. When calling a static member function, there is no this pointer .)

See example 4 (Copyright c ++ (2nd)> (copyright) page 1)
Class enemytarget {
Public:
Enemytarget () {++ numtargets ;}
Enemytarget (const enemytarget &) {++ numtargets ;}
~ Enemytarget () {-- numtargets ;}
Static size_t numberoftargets () {return numtargets ;}
Bool destroy (); // returns success of attempt to destroy enemytarget object
PRIVATE:
Static size_t numtargets; // object counter
};
// Class statics must be defined outside the class;
// Initialization is to 0 by default
Size_t enemytarget: numtargets;

In this example, the static data member numtargets is used to count the number of generated objects.

In addition, because the thread function pthread_create () in the POSIX database requires a global mechanism when designing multi-threaded operations, common member functions cannot be directly used as thread functions, you can use the static member function as a thread function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.