One student wrote this in the header file:
?
12 |
static
const wchar_t * g_str1 = …
static
const wchar_t * g_str2 = … |
This way of defining variables has never been seen before, and it can still be compiled smoothly, so I would like to know how the compiler handles this definition of variables.
When defining a global variable, use static, which means that the scope of the variable is limited to the source file that defines it, and other source files cannot be accessed. Since this definition method appears in the header file, it can be inferred naturally: the variables are defined in all the source files that contain the header file, that is, how many times the header file is contained, these variables define how many times.
If the static values of the above two lines of code are removed, the variable redefinition error will occur during compilation, which further confirms the above speculation, if there is no static variable, the scope of the variable is global. This error occurs when more than two variables with the same name are defined.
Speculation is speculation after all. To truly prove this speculation, We need to write code to verify it. The verification method is: use static to define a variable in the header file, include the header file in multiple source files, and then output the variable address in each source file, at the same time, the variable value is changed in one source file and output in another source file. If the output of each source file is different, we guess it is proved; otherwise, we guess it is wrong.
The following code defines the header file of a variable:
?
1234 |
//Header.h #pragma once
static
int g_int = 3; |
Next, declare two test functions in another header file:
?
12345 |
//Functions.h #pragma once
void TestSource1();
void TestSource2();
|
Define the two test functions in the two source files respectively:
?
12345678910 |
//Source1.cpp #include <stdio.h>
#include "Header.h"
void TestSource1() {
wprintf(L "g_int's address in Source1.cpp: %08x\n" , &g_int);
g_int = 5;
wprintf(L "g_int's value in Source1.cpp: %d\n" , g_int);
} |
?
123456789 |
//Source2.cpp #include <stdio.h>
#include "Header.h"
void TestSource2() {
wprintf(L "g_int's address in Source2.cpp: %08x\n" , &g_int);
wprintf(L "g_int's value in Source2.cpp: %d\n" , g_int);
} |
Finally, call the two test functions in the main function:
?
12345678 |
//Main.cpp #include "Functions.h"
int wmain() {
TestSource1();
TestSource2();
} |
Run the program:
As you can see, although the same variables seem to be used in the code, they actually use different variables and each source file has a separate variable. Therefore, defining static variables in the header file may cause multiple definitions of variables, resulting in a waste of memory space, and is not a real global variable. Avoid using this definition.
For comparison, the following uses the correct method to define global variables:
?
1234 |
//Header.h #pragma once
extern
int g_int; |
?
123456789101112 |
//Source1.cpp #include <stdio.h>
#include "Header.h"
int g_int = 3;
void TestSource1() {
wprintf(L "g_int's address in Source1.cpp: %08x\n" , &g_int);
g_int = 5;
wprintf(L "g_int's value in Source1.cpp: %d\n" , g_int);
} |
Other files remain unchanged.
Run the program:
We can see that the two source files use the same variable. Note that an initial value cannot be included when a variable is declared using extern. Otherwise, the variable is still defined and a variable definition error occurs.