Example of the C + + in the extern key word _c language

Source: Internet
Author: User
Tags constant function definition function prototype modifier

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

Which means that extern has two functions, the first one, when it is used with "C", such as: extern "C" void fun (int a, int b), tells the compiler to compile fun this function name, according to the rules of C to translate the corresponding function name rather than C + +, C + + The rule of translation of this function name will be the name of fun to become unrecognizable, may be fun@abc_int_int#%$ also may be other, this depends on the compiler's "temper" (different compilers adopt the same method), why do it, because C + + support functions of the overload Ah, Here not to discuss this problem too much, if you are interested can go online search, I believe you can get a satisfactory explanation!

Second, when extern does not modify a variable or function together with "C", as in a header file: extern int g_int; Its role is to declare the function or global variables of the scope of the keyword, its declared functions and variables can be used in this module live other modules, remember it is a declaration is not defined! That is, if the B module (the compilation unit) refers to a global variable or function defined in the module (compile unit) A, It only contains the header file of a module, in the Compile phase, Module B can not find the function or variable, but it will not error, it will be in the connection from module a generated from the target code to find this function.

2 questions: 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?

Answer and Analysis:

1, can not, the program will tell you when the operation of illegal access. The reason is that pointers to type T are not equivalent to arrays of type T. The extern char *a declares a pointer variable instead of a character array, and therefore differs from the actual definition, resulting in illegal access at run time. 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 code value), *a obviously meaningless

Obviously a point of space (0x61626364) is meaningless and prone to illegal memory access.

3, this prompts us, in the use of extern time to strictly correspond to the declaration when the format, in 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 you want to be referenced, put in the *.h and declared with extern.

3 problem: When the aspect modifies the extern function prototype

When the function provider modifies the function prototype unilaterally, the compiler will not make an error if the user does not knowingly continue with the original extern declaration. But in the running process, because less or more input parameters, often will be a system error, this situation should be how to solve?

Answer and Analysis:

Currently, the industry does not have a perfect solution for this situation, the common practice is that the provider in its own xxx_pub.h to provide a declaration of the external interface, and then the caller include the header file, thus eliminating the step of extern. To avoid this error.

The sword has two fronts, for the application of extern, different occasions should choose a different approach.

4 question: extern "C"

When using C functions in C + + environments, it is often possible that the compiler cannot find the C function definition in the OBJ module, causing the link to fail, and how to

Solve this situation?

Answer and Analysis:

The C + + language is compiled in order to solve the problem of function polymorphism, the function names and parameters will be combined to generate a middle of the functions of the name, and the C language will not, so will cause the link can not find the corresponding function, at this time the C function needs 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.

Here is a standard notation:

On the head of the. h file
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif #endif/
* __cplusplus */ 
... 
c7/> ... where the. h file ends
#ifdef __cplusplus
#if __cplusplus
}
#endif

5 question: extern function declaration

Often see extern placed in front of a function as part of a function declaration, so what does the C language keyword extern do in the declaration of a function?

Answer 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. That is, there are no obvious differences between the following two function declarations:

extern int f (); and int f ();

Of course, the use of this is in the program to replace the include "*.h" to declare functions, in some complex projects, I am more accustomed to all the function declarations before adding extern decoration. The reasons and pros and cons of doing so can be seen in the following example: "Global variables decorated with extern"

(1) The following declarations are made in the Test1.h:

#ifndef test1h
#define TEST1H
extern char g_str[];//DECLARE global variable g_str
void Fun1 ();
#endif

(2) in the Test1.cpp

#include "test1.h"
char g_str[] = "123456";//define global variable g_str
void Fun1 () {cout << g_str << Endl;}

(3) The above is the Test1 module, its compilation and connection can be passed, if we still have test2 module also want to use G_STR, just to be referenced in the original file can be

#include "test1.h"
void Fun2 () {cout << g_str << Endl;}

The above test1 and test2 can compile the connection at the same time, if you are interested in the UltraEdit open test1.obj, you can find the "123456" in the string, but you can't find in the Test2.obj, this is because g_ STR is the global variable for the entire project, only one in memory, test2.obj this compilation unit does not need to have a copy, or will be reported on the connection to repeat the definition of this error!

(4) Some people like to put the declarations and definitions of global variables together, so as to prevent forgetting the definition, such as changing 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, and when you 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 it defines a g_str, and Test2.cpp also contains Test1.h, so once again defines the G_STR, at which point the connector finds two test1 when connecting Test2 and G_str. If you have to put the definition of g_str in the Test1.h, then

In the Test2 code, #include "Test1.h" is removed and replaced by:

extern char g_str[];
void Fun2 () {cout << g_str << Endl;}

This time the compiler will know that G_str is a compilation 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, So you can't use the other functions declared in Test1.h, unless you also use the extern modifier, so that your light declaration function will be a large string, and the role of the header file is to provide external interface to use, so please remember, only in the header file declaration, truth is always so simple.

6. extern and Static

(1) extern indicates that the variable has been defined elsewhere, and that the variable is used here.

(2) Static to represent the variable, the allocation of memory, stored in the static area, not stored on the stack.

The static scope is a relationship of internal connections, which is a bit opposite to extern. It is stored separately from the object itself, and extern is stored separately, but extern can be referenced by other objects with an extern, and static is not allowed, only the object itself. The specific difference first, static and extern is a pair of "incompatible", that is, extern and static can not modify a variable at the same time, second, static-decorated global variable declarations and definitions, That is, when you declare a global variable with static in the header file, it is defined at the same time; Finally, the scope of the static cosmetic global variable can only be its own compilation unit, which means that its "global" only

Valid for this compilation unit, 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 compile units can connect successfully, when you open test1.obj, you can find the string "123456" inside it, And you can also find them in the test2.obj, they can connect successfully without reporting duplicate definitions because although they have the same content, the stored physical addresses are not the same, like two different variables assigned the same value, and the two variables are used for their respective compilation units. Maybe you're more serious, you secretly track debugging the above code, the result you found that two compilation unit (TEST1,TEST2) of the G_STR memory address is the same, so you conclude that the static modified variable can also be used in other modules, but I want to tell you that it is your compiler in the deception you, Most compilers have optimized functionality for the code, in order to achieve the generated target program is more memory-saving, execution more efficient, when the compiler connected to each of the compilation units, it will be the same content of the memory only copies, such as the above "123456", in two of the compilation unit variables are the same content, Then in the connection it will only exist in memory, if you change the above code to look like the following, you can immediately debunk the compiler 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 you are tracking the code, you will find that the two compilation units of the G_STR address is not the same, because you modify it in one place, so the compiler is forced to restore the original memory, in memory there are two copies of the two modules in the use of variables. It is because the static has the above characteristics, so the general definition static global variable, it is placed in the original file rather than the header file, so that the other modules do not cause unnecessary information pollution, but also 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 the const can 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, don't forget to define: const char g_str[] = "123456";

So when the const is used alone it is the same as static, and when working with extern, it has the same characteristics as extern! So for the const I have nothing to describe too much, I just want to remind you that the 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 a constant, it is considered to be a defined global variable (which can be used by other compilation units), so if you like to let Char*g_str obey the rules of const global constants, it is best to define the const char* Const g_str= "123456 ".

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.