An explanation of the extern keyword in C + +

Source: Internet
Author: User
Tags modifier variable scope

Transfer from chao_yu,cnblog.com

1 Basic explanation : extern can be placed before a variable or function to indicate the definition of a variable or function in another file, prompting the compiler to find its definition in other modules when encountering this variable and function. Also extern can be used for link designation.

That is, the extern has two functions, the first, when it is in conjunction with "C", such as: extern "C" void fun (int a, int b); then tell the compiler to compile the function name of fun by the C rule to translate the corresponding function name instead of C + + The rules in the translation of this function name will be the name of the fun to become unrecognizable, may be [email protected]_int_int#%$ may also be other, this depends on the compiler's "temper" (different compiler uses the same method), why do it, because C + + Support functions of the overloaded 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!
Second, when extern does not modify the variable or function together with "C", as in the header file: extern int g_int; Its function is to declare the function or global variable scope of the keyword, its declared functions and variables can be used in other modules of this module, remember that it is a declaration is not a definition! That is, if the B module (the compilation unit) refers to a global variable or function defined in a module (compilation unit), As long as it contains the header file of the A module, in the compilation phase, module B, although it cannot find the function or variable, but it does not error, it will be in the connection when the module a generated from the target code to find this function.

2 problem:extern variable
An array is defined in a source file: Char a[6];
In another file, it is declared with the following statement: extern char *a;
Excuse me, is this OK?
Answers and Analysis:
1), no, the program will tell you illegal access to run. The reason is that pointers to type T are not equivalent to arrays of type T. extern Char *a declares a pointer variable instead of a character array, and therefore differs from the actual definition, resulting in illegal access by the runtime. The declaration should be changed to extern char a[].
2), example analysis as follows, if a[] = "ABCD", then the external variable a=0x61626364 (ABCD ASCII value), *a obviously meaningless
Obviously a points to a space (0x61626364) that has no meaning and is prone to illegal memory access.
3), this prompts us, in the use of extern time to strictly correspond to the format of the declaration, in the actual programming, such errors are not uncommon.
4), extern used in variable declarations often have such a role, you declare a global variable in the *.C file, the global variable if it is to be referenced, it is placed in the *.h and the extern to declare.

3 problem: Modifying the extern function prototype when facet
When a function prototype is modified unilaterally by the provider, if the user does not knowingly continue to follow the original extern declaration, the compiler does not give an error. However, in the process of running, because less or more input parameters, often as a system error, this situation should be how to solve?
Answers and Analysis:
The industry does not have a perfect solution for this situation at the moment, and it is common practice for the provider to provide a declaration of the external interface in its own xxx_pub.h, and then the caller includes the header file, eliminating the need for an extern step. To avoid such errors.
Sword has two fronts, the application of extern, different occasions should choose different practices.

4 problem:extern "C"
When using C functions in a C + + environment, it is often the case that the compiler cannot find the C function definition in the OBJ module, which causes the link to fail, how should it be resolved?

Answers and Analysis:
C + + language at compile time in order to solve the problem of polymorphic functions, the function name and parameters will be combined to generate an intermediate function name, and the C language will not, so the link can not find the corresponding function, the C function will need to use extern "C" for the link designation, which tells the compiler, Please keep my name and don't give me the middle function name for the link.
The following is a standard notation:
On the head of the. h file
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif/* __cplusplus */
...
...
where the. h file ends
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif/* __cplusplus */

5 problem:extern function Declaration
It is often seen that extern is placed in front of the function as part of the function declaration, so what does the C keyword extern do in the declaration of a function?
Answers and Analysis:
If the declaration of a function has the keyword extern, it simply implies that the function may be defined in another source file, with no other effect. There is no obvious difference between the following two function declarations:
extern int f (); and int f ();
Of course, the usefulness of this is to replace the include "*.h" in the program to declare the function, and in some complex projects, I am more accustomed to adding extern adornments before all function declarations. The reasons and pros of doing this can be seen in the following example: "Global variables modified with extern"

(1) The following statements are made in Test1.h:
#ifndef test1h
#define TEST1H
extern Char g_str[]; Declaring Global Variables G_str
void Fun1 ();
#endif
(2) in the Test1.cpp
#include "Test1.h"
Char g_str[] = "123456"; Defining Global Variables G_str
void Fun1 () {cout << g_str << Endl;}
(3) 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 find the "123456" in the 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!
(4) 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 test1.cpp in the g_str removed, this time to compile the connection test1 and test2 two modules, the connection error is reported, because you put the definition of the global variable g_str after the header file, Test1.cpp This module contains Test1.h so defines a g_str, and Test2.cpp also contains test1.h so once again the G_STR is defined, when the connector finds two test1 when connecting Test2 and G_str. 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

6. extern and Static

(1) extern indicates that the variable has already been defined elsewhere, and that variable is used here.
(2) static variable, when allocating memory, is stored in the static zone, not stored on the stack.

The static scope is the internal connection, and the extern is somewhat opposite. It is stored separately from the object itself, and extern is stored separately, but extern can be referenced by other objects with extern, and static cannot, only allow the object itself to use it. Specific differences first, static and extern is a pair of "fire and Fire" of the guy, that is, extern and static can not modify a variable at the same time, and second, the static 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 the static 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:
(1) Test1.h:
#ifndef test1h
#define TEST1H
static char g_str[] = "123456";
void Fun1 ();
#endif

(2) Test1.cpp:
#include "Test1.h"
void Fun1 () {cout << g_str << Endl; }
(3) 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, and the two variables for their respective compilation unit. Perhaps you are more serious, your own secretly tracking debug the above code, the result you find two compilation unit (TEST1,TEST2) of the G_STR memory address is the same, so you conclude that static modified variables can also act on other modules, but I want to tell you, that is your compiler is cheating 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 immediately expose the compiler's lies:
(1) Test1.cpp:
#include "Test1.h"
void Fun1 ()
{
G_str[0] = "a";
cout << g_str << Endl;
}

(2) Test2.cpp
#include "Test1.h"
void Fun2 () {cout << g_str << Endl; }
(3) 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!

7. extern and const

The const-decorated global constants in C + + have the same characteristics as static, that is, they can only be used in this compilation module, but a const may be used with an extern connection to declare that the constant can function in other compilation modules, such as extern const char g_str[];
Then in the original file do not forget the definition: const char g_str[] = "123456";

So when the const is used alone it is the same as static, and when working with extern, its characteristics are the same as extern! So for const I have nothing to describe too much, I just want to remind you that const char* G_STR = "123456" is different from the const char g_str[] = "123465" and the previous const modifier is char * instead of G_STR , its g_str is not 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 of the rules, it is best to define the const char* Const g_str= "123456 ".

An explanation of the extern keyword in C + +

Related Article

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.