Explanation of the extern keyword in C/C ++ and the extern keyword

Source: Internet
Author: User

Explanation of the extern keyword in C/C ++ and the extern keyword
1. Basic explanation

  ExternCan be placed inVariableOrBefore FunctionTo indicateDefinitionInOther filesWhen the compiler encounters this variable and function, it is prompted to find its definition in other modules. In addition, extern can also be usedLink specified.

That is to say, extern has two functions:

A. When it corresponds"C"For example, extern "C" void fun (int a, int B ).C RulesTranslate the corresponding function name instead of the C ++. The C ++ rule will make the fun name invisible when translating this function name, it may be fun @ aBc_int_int # % $ or something else. It depends on the "temper" of the compiler (the methods used by different compilers are different). Why, because C ++ supports function overloading, I will not discuss this issue too much here. If you are interested, you can search online. I believe you can get a satisfactory explanation!

B. When externNot with "C"When modifying variables or functions together, for example, in the header file: extern int g_Int; its function isDeclare a functionOrGlobal VariablesOfScopeKeyword. The declared functions and variables can be used in other modules in this module. Remember that it is a declaration, not a definition! That is to say, if Module B (compilation unit) references the global variables or functions defined in module A, it only needs to include the header file of module A. During the compilation phase, although Module B cannot find this function or variable, it does not report an error. It will find this function from the target code generated by module A during connection.

2. Problem: extern variable

An array is defined in a source file:Char a [6]In another file, use the following statement:Extern char *Could you do this?
Answer and analysis:
1) No. Illegal access will be reported during the program running. The reason is that the pointer to type T is not equivalent to the array of type T.Extern char *DeclarePointer variableWhileNot a character arrayTherefore, it is different from the actual definition, resulting in invalid access during runtime. Change the statementExtern char a [].
2) The example analysis is as follows. If a [] = "abcd", the external variable a = 0x61626364 (the ASCII code value of abcd), * a is obviously meaningless, obviously, the space (0x61626364) that a points to is meaningless and prone to illegal memory access.
3) This reminds us that we must strictly match the declared format when using extern. In actual programming, such errors are not uncommon.
4) extern is often used in variable declaration.*. C fileDescriptionA global variableIf the global variable is to beReference, Put it in*. HAndExtern to declare.

3. Problem: unilaterally modify the prototype of the extern Function

When the FunctionThe provider unilaterally modifies the function prototype.If the user does not know how to continue using the original extern statement, the compiler will not report an error during compilation. However, during the running process, a system error is often caused by missing or missing input parameters. How can this problem be solved?
Answer and analysis:
Currently, there is no perfect solution in the industry to deal with this situation. The common practice isProviderIn your own xxx_pub.hProvide external interface declaration, And thenCaller include this header fileTo save the extern step. To avoid such errors. Baojian has a dual front. For the application of extern, different practices should be selected for different occasions.

4. Problem: extern "C"

When using C functions in the C ++ environment, the compiler often appears.The C function definition in the obj module cannot be found.How can this problem be solved if the link fails?

Answer and analysis:
  C ++ LanguageDuring compilationFunction Polymorphism, WillFunction NameAndParametersGenerateIntermediate function name, AndC LanguageTherefore, the corresponding function cannot be found during the link. In this case, the C function needs to useExtern "C"ProceedLink specifiedThis tells the compiler that keep my name and do not generate an intermediate function name for the link.
The following is a standard syntax:

1 // In. h file header 2 # ifdef _ cplusplus 3 # if _ cplusplus 4 extern "C" {5 # endif 6 # endif/* _ cplusplus */7... 8... 9 // 10 # ifdef _ cplusplus11 # if _ cplusplus12} 13 # endif14 # endif/* _ cplusplus */

 

5. Problem: extern function declaration

Often seeExternPut inBefore the FunctionAs part of the function declaration, what is the role of the C language keyword extern in the function declaration?
Answer and analysis:
If the function declaration contains the keyword extern, it only implies that the function may be defined in other source files and has no other function. There is no obvious difference between the following two function declarations:
Extern int f (); and int f ();
Of course, such usefulness is still available in the program.Replace include "*. h"ComeDeclare a functionIn some complex projects, I prefer to add the extern modifier before all function declarations. The following example shows the reasons and advantages: "global variables modified with extern"

(1) The following statements are contained in test1.h:

1 # ifndef TEST1H2 # define TEST1H3 extern char g_str []; // declare the global variable g_str4 void fun1 (); 5 # endif

(2) In test1.cpp

1 # include "test1.h" 2 char g_str [] = "123456"; // define the global variable g_str3 void fun1 () {cout <g_str <endl ;}

(3) The above is the test1 module, which can be compiled and connected. If we still have the test2 module and want to use g_str, we only need to reference it in the original file.

1 #include "test1.h"2 3 void fun2() { cout << g_str << endl; }

The above test1 and test2 can be compiled and connected at the same time. If you are interested, you can use ultraEdit to open test1.obj. You can find the string "123456" in it, but you cannot find it in test2.obj. This is because g_str is the global variable of the entire project and only one copy exists in the memory. The test2.obj compilation unit does not need to have one more copy, otherwise, this error will be repeatedly reported during connection!

(4) Some people like to put together the Declaration and definition of global variables to avoid forgetting the definition. For example, change test1.h

1 extern char g_str [] = "123456"; // This time is equivalent to no extern

Then, remove the g_str definition in test1.cpp. When the test1 and test2 modules are compiled and connected again, a 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 it defines g_str once, And test2.cpp also contains test1.h so it defines g_str again. At this time, the connector finds two g_str pairs when connecting test1 and test2. If you want to put the g_str definition in test1.h, replace # include "test1.h" in test2 code:

1 extern char g_str[];2 void fun2() { cout << g_str << endl; }

At this time, the compiler will know that g_str is an external compilation module and will not be repeatedly defined in this module, but I would like to say this is very bad, because you cannot use # include "test1.h" in test2.cpp, other functions declared in test1.h cannot be used unless they are modified with extern, in this case, you need to declare a large string of functions, and the role of the header file is to provide external interfaces for use. Therefore, remember to only declare the header file. The truth is always so simple.

6. extern and static

(1)ExternIndicates that the variable is inDefined elsewhereThe variable is used here.
(2)StaticIndicatesStatic variablesWhen memory is allocatedStatic Zone, Not stored on the stack.

  Static ScopeYesInternal ConnectionAnd extern. It is stored separately from the object itself, and extern is also stored separately,ExternYesReferenced by other objects using extern, AndStatic is not allowedOnly allow the object to use it. first of all, static and extern are a pair of "fire cannot be" guys, that is, extern and static cannot modify a variable at the same time. Second, the static modified global variables are declared and defined at the same time, that is to say, when you useStaticDeclaredGlobal VariablesIt alsoAlso definedFinally,StaticModifyScope of global variablesOnly yesCompilation UnitThat is to say, its "global" is only valid for the current compilation unit,Other compilation unitsThenCannot see itSuch:
(A) test1.h:

1 #ifndef TEST1H2 #define TEST1H3 static char g_str[] = "123456"; 4 void fun1();5 #endif

(B) test1.cpp:

1 #include "test1.h"2 void fun1() { cout << g_str << endl; }

(C) test2.cpp

1 #include "test1.h"2 void fun2() { cout << g_str << endl; }

The above two compilation units can be connected successfully. When you open test1.obj, you can find the strings "123456" in it, and you can also find them in test2.obj, the reason why they can be connected successfully without repeatedly defining errors is that although they have the same content, they store different physical addresses, just as two different variables assigned the same value, the two variables act on their respective compilation units. Maybe you are more serious. You secretly track and debug the above Code. As a result, you find that the memory address of g_str of two compilation units (test1, test2) is the same, so you can conclude that static modified variables can also be applied to other modules, but I want to tell you that your compiler is deceiving you, and most compilers have optimized functions for the code, in order to achieve the generation of the Target Program, the memory is reduced and the execution efficiency is higher. When the compiler connects to each compilation unit, it will copy only one copy of the memory with the same content, for example, in the above "123456", the variables in the two compilation units are the same content, so it will only exist in the memory during the connection, if you change the code above to the following, you can immediately crack the lies of the compiler:

(A) test1.cpp:

1 #include "test1.h"2 void fun1()3 {4 g_str[0] = ''a'';5 cout << g_str << endl;6 }

(B) test2.cpp

1 #include "test1.h"2 void fun2() { cout << g_str << endl; }

(C) main. cpp

1 void main() {2     fun1(); // a234563     fun2(); // 1234564 }

At this time, when you track the code, you will find that the g_str address in the two compilation units is not the same, because you modified it in one place, so the compiler is forced to restore the original memory, there are two copies in the memory to use the variables in the two modules. It is precisely because static has the above features that, when defining static global variables, it is usually put in the original file rather than the header file, so that it will not cause unnecessary information pollution to other modules, remember this principle!

7. extern and const

The global constants modified by const in C ++ have the same characteristics as static, that is, they can only act on this compilation module,ConstYou canUse externTo declare the constant.Acting on other compilation modules, Such as extern const char g_str [];
Do not forget to define const char g_str [] = "123456 ";

So when the const is used independently, it is the same as static, and when it is used together with extern, its features are the same as extern! So I can't describe const too much. I just want to remind you that const char * g_str = "123456" is different from const char g_str [] = "123465, the preceding const modifies char * rather than g_str. Its g_str is not a constant and is regarded as a defined global variable (which can be used by other compilation units ), therefore, if you want char * g_str to follow the global constant rules of const, it is better to define const char * const g_str = "123456 ".

 

Link: http://www.cnblogs.com/qintangtao/archive/2012/12/04/2801693.html

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.