Basic knowledge
extern usage, global variables and header files (duplicate definition)
Transfer from
https://www.cnblogs.com/chengmin/archive/2011/09/26/2192008.html
When you want to reference a global variable, you have to declare it, extern int a; At this time, extern cannot be omitted, because if omitted, it becomes int a; this is a definition, not a declaration.
Use #include to include declarations of variables and functions in other header files. Why the extern keyword? If I want to reference a global variable or function a, I just need to include #include <xxx.h> (xxx directly in the source file .h contains the declaration of a) isn't it? Why use extern? ? This problem has also been puzzling me for many years, and today I went to the Internet to check it fiercely and finally got a little:
head File
First, let's talk about the header file. In fact, the header file has no effect on the computer. She just expanded it in the #include place during pre-compilation. It has no other meaning. In fact, the header file is mainly for others to see.
I did an experiment, changed the suffix of the header file to xxx.txt, and then used where the header file was referenced
#include "xxx.txt"
Compiling and linking went smoothly. From this we can see that the header file is only for reading the code, and has no other effect!
Regardless of whether it is C or C ++, you put your functions, variables or structs, or classes in your .c or .cpp file. Then compile it into lib, dll, obj, .o and so on, and then the most basic gcc hisfile.cpp yourfile.o | obj | dll | lib and so on when others use it.
But for us programmers, how do they know what's in your lib, dll ...? It depends on your header file. Your header file is a description of the user. Functions, parameters, and descriptions of various interfaces.
Since that is the description, then the header files are naturally about the "declaration" of functions, variables, and classes. Remember, it's a "statement", not a "definition".
So, I assume you know the difference between a declaration and a definition. Therefore, it's best not to be silly about defining something in the header file. For example global variables:
#ifndef _XX_ Header File.H
#define _XX_ header file.H
int A;
#endif
Well, the bad thing is that int A here is a global variable definition, so if this header file is referenced multiple times, your A will be repeatedly defined
Obviously the syntax is wrong. It's just that the conditional compilation of #ifndef can guarantee that your header file is only referenced once, but it may still be a mistake, but if multiple c files include this header file, an error will still occur because the valid range of the macro name It is limited to this c source file, so there will be no error when compiling multiple c files, but an error will be reported when linking, saying that you have defined the same variable in multiple places,
Linking ...
incl2.obj: error LNK2005: "int glb" (? glb @@ 3HA) already defined in incl1.obj
Debug / incl.exe: fatal error LNK1169: one or more multiply defined symbols found
note! !! !!
extern
This keyword is really abominable. When it is declared, this extern can be omitted, so it will make you wonder whether it is declared or defined. The following are divided into two types: variables and functions:
(1) Variable
Especially for variables.
extern int a; // declare a global variable a
int a; // Define a global variable a
extern int a = 0; // Define a global variable a and give it an initial value.
int a = 0; // Define a global variable a, and give the initial value,
The fourth is equal to the third, both define a global variable that can be used externally and give an initial value.
Confused, they look real. But definitions can only appear in one place. In other words, whether it is int a; or extern int a = 0; or int a = 0; can only appear once, and that extern int a can appear many times.
When you want to reference a global variable, you have to declare it, extern int a; At this time, extern cannot be omitted, because if omitted, it becomes int a; this is a definition, not a declaration.
(2) Functions
Functions, functions, and functions are also the same. They are also defined and declared. When defining, use extern to indicate that the function can be externally referenced. When declaring, use extern to indicate that this is a declaration. However, because function definitions and declarations are different, function definitions must have function bodies, and function declarations do not have function bodies, so extern can be omitted when defining and declaring functions. Anyway, other files also know that this function is defined elsewhere Yes, so without extern. The two are so different that omitting extern is not a problem.
such as:
int fun (void)
{
return 0;
}
Good, we have defined a global function
int fun (void);
We make a statement about it, and we can use it later
With or without extern
We can also put the declaration of fun in a header file, and finally become like this
int fun (void); // The function declaration, so extern is omitted, more complete is extern int fun (void);
int fun (void)
{
return 0;
} // A complete global function definition, because there is a function body, extern is also omitted.
Then, a client, a client who wants to use your fun, include this header file, ok, a global declaration. no problem.
However, correspondingly, if this customer wants to use global variables, then extern must be used; otherwise, it will become a definition.
In summary:
For variables, if you want to use a variable from another source file in this source file, you need to declare the variable with extern before using it, or declare the variable with extern in the header file;
For functions, if you want to use a function from another source file in this source file, you need to declare the variable before using it. It does not matter if the function is declared with or without extern, so the function can be added without extern in the header file.
The C program uses a modular programming concept. It is necessary to reasonably divide a large piece of software into a series of functionally independent parts to complete the system's requirements. The division of modules is mainly based on functions. A module consists of a header file and an implementation file. The correct way to use the header file and the implementation file is:
The header file (.h) of Rule 1 is a declaration of the module's interface. The interface includes external functions and external global variables provided by the module to other modules. These variables and functions must be extern in the .h file. Keyword declaration
Rule 2 Functions and global variables in the module must be declared with the static keyword at the beginning of the .c file;
Rule 3 Never define variables in .h files;
Many programmers are confused about defining variables and declaring variables. The difference between defining variables and declaring variables is that defining operations that generate memory allocation is a concept in the assembly phase; declarations only tell the module that contains the declaration from other The module looks for external functions and variables. Such as:
int a = 5;
#include "module1.h"
#include "module1.h"
#include "module1.h"
The result of the above program is that integer variables a are defined in modules 1, 2, and 3, and a corresponds to different address units in different modules, which obviously does not meet the original intention of the writer. The correct way is:
extern int a;
#include "module1.h"
int a = 5;
#include "module1.h"
#include “module1.h”
In this way, if modules 1, 2, and 3 operate a, they correspond to the same memory unit.
Rule 4 If you want to use variables and functions defined by other modules, just include their header files directly.
Many programmers like to do this. When they want to access variables defined by other modules, they add such statements at the beginning of this module file:
extern int externVar;
Abandon this approach, as long as the header file is completed according to rule 1, when a module wants to access the global variables defined in other modules, it only needs to include the module's header file.
Shared variable declaration
Just like how variables are shared between functions, variables can be shared among files. In order to share a function, the definition of the function is placed in a source file, and declarations are placed in other files that need to call this function. The method for sharing variables is very similar.
Until then, there is no need to distinguish between the declaration of a variable and its definition. To declare the variable i, write the following:
int i;
This not only declares that i is a variable of type int, but also defines i, thus leaving the compiler with space for i. In order to declare an undefined variable i, the keyword extern needs to be placed at the beginning of the variable declaration:
extern int i;
extern hints that the compiler variable i is defined elsewhere in the program (most likely in a different source file), so there is no need to allocate space for i.
By the way, extern can be used for all types of variables. When using extern in an array declaration, you can ignore the length of the array:
extern int a [];
Because the compiler does not need to allocate space for array a at this time, it does not need to know the length of array a.
To share the variable i in several source files, first place the definition of the variable i in a file:
int i;
If you need to initialize the variable i, you can put the initial value here. When compiling this file, the compiler will allocate memory for variable i, while other files will contain declarations for variable i:
extern int i;
By declaring the variable i in each file, the variable i can be accessed / modified in these files. However, the keyword extern prevents the compiler from allocating extra memory space to the variable i every time one of the files is compiled.
When sharing variables in files, you face a similar challenge to sharing functions: ensuring that all declarations and definitions of variables are consistent.
To avoid conflicts, declarations of shared variables are usually placed in header files. Source files that need access to special variables can later include the appropriate header files. In addition, the source file containing the variable definition includes every header file containing the variable declaration, so that the compiler can check whether the two match.
If the project is large and there are many header files, and there are several header files that are often used, then
1. Write all these header files into a header file, such as preh.h
2. Write a preh.c with only one sentence: #include "preh.h"
3. For preh.c, set creat precompiled headers in the project setting, for other
c file, set use precompiled header file