Static and extern

Source: Internet
Author: User

The following are from: http://blog.csdn.net/cclive1601/article/details/8063505

Some basic concepts:

1. Compilation unit (module):
In the IDE development tools of the big line of the today, some of the concepts of compilation is no longer clear, many programmers are most afraid of is to deal with connection errors (link error), because it is not like a compilation error can give you the exact location of the program error, you are often upset about this error, But if you often use tools such as Gcc,makefile in Linux or embedded under the development work, then you may very well understand the difference between the compilation and the connection! When the VC such development tools to write code, click the Compile button ready to generate EXE file, VC actually did two steps, the first step, will each. cpp (. c) and the corresponding. h files are compiled into obj files; the second step is to link all the obj files in the project to generate the final. exe file, then the error can be generated in two places, one is a compile-time error, this is mainly a syntax error, and the other is a connection error, mainly repeating the definition of variables and so on. What we call a compilation unit is that each obj file generated during the compile phase, an obj file is a compilation unit, that is, a CPP (. c) and its corresponding. h file together make up a compilation unit, and a project consists of a number of compilation units, Each obj file contains the relative address of the variable store, and so on.

2. Differences between declarations and definitions
when a function or variable is declared, it does not give it actual physical memory space, it can sometimes guarantee that your program compiles, but when the function or variable is defined, it has the actual physical space in memory, If the external variable that you reference in the compilation module is not defined anywhere in the entire project, even though it can be passed at compile time, it will error when connecting, because the program cannot find this variable in the memory! You can also understand that the declaration of the same variable or function can be repeated more than once, but only once!

3. The role of extern
extern has two functions, the first one, when it is combined with "C", such as: extern "C" void fun (int a, int b); Then tell the compiler to compile the function name of fun, according to the C rules to translate the corresponding function name instead of C + + , C + + rules in the translation of this function name will be the name of the fun to become unrecognizable, may be [email protected]_int_int#% $ also may be other, this depends on the compiler's "temper" (different compiler uses the same method), why do it, because C + + support function overload Ah, here do not go too much to discuss the problem, if you are interested can go online search, I believe you can get a satisfactory explanation!
when extern does not decorate a variable or function with "C", as in a header file: extern int g_int; it functions as a keyword that declares the scope of a function or global variable, and its declared functions and variables can be used in this module or in other modules . Remember that it is a statement that is not defined! In other words, if the B module (compilation unit) refers to a global variable or function defined in the module (compilation unit) A, it only contains the header file of the A module, and in the compilation phase, module B cannot find the function or variable, but it does not error, it will find this function from the target code generated by module a during connection.

If you have a good understanding of the above concepts, let's take a look at the following differences in the use of global variables/constants:

1. Global variables modified with extern
The above has been said the role of extern, let us give an example, such as:
The following declarations are made in Test1.h:
#ifndef test1h
#define TEST1H
extern Char g_str[]; Declaring Global Variables G_str
void Fun1 ();
#endif
In the Test1.cpp
#include "Test1.h"

Char g_str[] = "123456"; Defining Global Variables G_str

void Fun1 ()
{
cout << g_str << Endl;
}

The above is the Test1 module, its compilation and connection can pass, if we have test2 module also want to use G_STR, only need to reference in the original file can be
#include "Test1.h"

void Fun2 ()
{
cout << g_str << Endl;
}
The above test1 and test2 can compile the connection through at the same time, if you are interested in the words can be opened with UltraEdit test1.obj, you can be inside the "123456" this string, but you can't find in Test2.obj, this is because g_ STR is a global variable for the entire project, there is only one copy in memory, test2.obj this compilation unit does not need another copy, otherwise it will report a duplicate definition of this error at the time of connection!
Some people like to put the declaration and definition of global variables together, so as to prevent forgetting the definition, such as to change the above Test1.h to
extern char g_str[] = "123456";//This time is equivalent to no extern
Then the definition of the G_STR in the Test1.cpp is removed, this time again to compile the connection test1 and test2 two modules,will report a connection error, this is because you put the definition of the global variable G_str in the header file, Test1.cpp This module contains test1.h so define a g_str, and Test2.cpp also contains test1.h so once again define G_STR,this time the connector found two g_str when connecting Test1 and Test2. If you want to put the definition of g_str in the Test1.h, then the Test2 code in the # include "Test1.h" is removed instead:
extern Char g_str[];
void Fun2 ()
{
cout << g_str << Endl;
}
This time the compiler knows that G_STR is a compiled module from the outside, and will not be defined again in this module, but I would like to say that this is very bad because you cannot use # include "Test1.h" in Test2.cpp. Then the other functions declared in the test1.h you can not use, unless you also use the extern decoration, so that you declare the function of the light is a large string, and the role of the head file is to provide external interface to use, so remember,just make a statement in the header file, the truth is always so simple

2. Global variables modified with static
First of all, I'm going to tell you that static and extern are a couple of " Fire and Fire" guys, which means that extern and static cannot modify a variable at the same time, and second, thestatic modification of the global variable declaration and definition at the same time , That is, when you declare a global variable with static in a header file, it is defined at the same time, and finally, the scope of thestatic modifier global variable is only its own compilation unit , that is, its "global" is only valid for this compilation unit, and other compilation units do not see it, such as:
Test1.h:
#ifndef test1h
#define TEST1H
static char g_str[] = "123456";
void Fun1 ();
#endif

Test1.cpp:
#include "Test1.h"

void Fun1 ()
{
cout << g_str << Endl;
}

Test2.cpp
#include "Test1.h"

void Fun2 ()
{
cout << g_str << Endl;
}

The above two compilation units can be connected successfully, when you open test1.obj, you can find the string "123456" in it, At the same time you can find them in test2.obj, they can be connected successfully without repeating the definition of the error because although they have the same content, but the physical address of the storage is not the same, like two different variables assigned the same value, andThese two variables are used for each of their respective compilation units.
Perhaps you are more serious, your own secretly tracking debug the above code, the results you found two compilation units (Test1, test2) of the G_STR memory address is the same, so you can conclude that the static modified variable may also act on other modules, but I want to tell you, that is your compiler is deceiving you, Most compilers have the ability to optimize the code to achieve the resulting target program more memory-saving, more efficient execution, when the compiler is connected to each compilation unit, it will be the same content of the memory copy only one copy, such as the above "123456", in the two compilation unit variables are the same content, Then it will only exist in memory at the time of the connection, if you change the above code to look like this, you can immediatelydebunk the compiler's lies:
Test1.cpp:
#include "Test1.h"

void Fun1 ()
{
g_str[0] = ' a ';
cout << g_str << Endl;
}

Test2.cpp
#include "Test1.h"

void Fun2 ()
{
cout << g_str << Endl;
}

void Main ()
{
Fun1 (); a23456
Fun2 (); 123456
}

This time when you are tracking the code, you will find that the G_STR address in the two compilation unit is not the same, because you modify it in one place, so the compiler is forcibly restored to the original memory , in memory there are two copies of the two modules in the use of variables.

It is because of the above characteristics of static, so the general definition of static global variables, it is placed in the original file instead of the header file, so that the other modules will not cause unnecessary information pollution, the same thing to remember this principle!

3 Const-Modified global Constants (const summary of MS is not very good, next time if there are good articles reproduced!) )

Const-Modified global constants are used extensively, such as error message strings in software that are defined with global constants. the const-modified global constants have the same characteristics as static (conditional, thanks to SSWV's reminders, the const is placed in a read-only static store), i.e. they can only be used in this compilation module, However, a const can be used with an extern connection to declare that the constant can act on other compilation modules , such as
extern const Char g_str[];
Then, in the original file, don't forget to define:
const char g_str[] = "123456";

So when the const is used alone it is the same as static, (provided that all are describing global variables, if they are not the same inside the function) and when working with extern, it has the same characteristics as extern! So for const I don't have much to describe, I just want to remind you that const char* G_STR = "123456" is different from the const char g_str[] = "123465", the previous const modifier is char * and Not G_STR, its g_str is not a constant, it is considered a defined global variable (can be used by other compilation units), so if you like to let Char *g_str abide by the const global constants rules, it is best to define the const char* Const g_str= "123456".

One, c program storage space layout

The C program has been composed of the following parts:

1) The machine instruction part that the body section--CPU executes; a program has only one copy; read-only to prevent the program from modifying its own instructions due to an accident;

2) Initialize the data segment (data segment)--All the global variables assigned the initial value in the program, stored here.

3) Non-initialized data segment (BSS segment)--global variable not initialized in the program; the kernel initializes this segment to 0.

4) Stack-growth direction: top-down growth, automatic variables and the information (return address; Environment information) needed to be saved each time the function is called.

5) heap--dynamic storage points.

|-----------|

| |

|-----------|

| Stack |

|-----------|

|          | |

| /|/        |

| |

| |

| /|/        |

|          | |

|-----------|

| Heap |

|-----------|

| Uninitialized |

|-----------|

| Initialize |

|-----------|

| Body Segment |

|-----------|

Ii. static in process-oriented programming

1. Global static variables

The global variable is defined as a global static variable by adding the keyword static before the global variable.

1) in-memory location: static storage (static storage is present during the entire program run)

2) Initialize: Uninitialized global static variable is automatically initialized to 0 by the program (the value of the automatic object is arbitrary unless he is displayed initialized)

3) Scope: Global static variables are not visible outside the declaration of his file. Start with the definition exactly to the end of the file.

Look at the following program on scopes:

teststatic1.c

void display ();

extern int n;

int main ()

{

n = 20;

printf ("%d/n", N);

Display ();

return 0;

}

Teststatic2.c

static int n; Define global static variables, automatically initialized to 0, only visible in this file

void display ()

{

n++;

printf ("%d/n", N);

}

The files are compiled separately, but when link is teststatic1.c, the variable n cannot be defined, resulting in an error.

Benefits of defining global static variables:

<1> will not be accessed by other files, modify

<2> other files can use variables of the same name, and no conflicts will occur.

2. Local static variables

The local variable is defined as a local static variable by adding the keyword static before the local variable.

1) in-memory location: Static Storage Area

2) Initialize: Uninitialized global static variable is automatically initialized to 0 by the program (the value of the automatic object is arbitrary unless he is displayed initialized)

3) Scope: The scope is still a local scope, and when the function or statement block defining it ends, the scope ends.

Note: When static is used to modify a local variable, it changes the location where the local variable is stored and changes from the original stack to a static storage area. But the local static variable is not destroyed after it leaves the scope, but still resides in memory until the program is finished, but we can no longer access it.

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

3. Static functions

The function is defined as a static function by adding the keyword static before the return type of the function.

The definition and declaration of a function is extern by default, but the static function is only visible in the file that declares him and cannot be used by other files.

For example:

teststatic1.c

void display ();

static void Staticdis ();

int main ()

{

Display ();

Staticdis ();

Renturn 0;

}

Teststatic2.c

void display ()

{

Staticdis ();

printf ("Display () has been called/n");

}

static void Staticdis ()

{

printf ("Staticdis () has been called/n");

}

The files are compiled separately, but the definition of the function Staticdis () is not found when connecting, resulting in an error.

Benefits of defining static functions:

<1> other files can define the same name function, no conflict

<2> static functions cannot be used by other files.

Storage descriptor auto,register,extern,static, corresponding to two storage periods: automatic storage period and static storage period.

Auto and register correspond to automatic storage periods. A variable with an automatic storage period is established when it enters the block that declares the variable, it exists when the block is active, and is revoked when it exits the block.

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

Because of the above characteristics of the static variable, some specific functions can be implemented.

1. Number of 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 each time it is called. This is the best way to count the number of functions being called, because this variable is closely related to the function, and the function may be called in many different places, so it is difficult to count from the caller's point of view. 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, "times/n");

}

The output is:

I have been called 1 times.

I have been called 2 times.

I have been called 3 times.

Static and extern

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.