First, preface
In C-language code or C + + code, macro definition #ifndef ... #define ... #endif主要是为了避免头文件重复引用, how is it a avoidance mechanism? This is related to the scope of the macro definition.
Two, macro definition scope
First, the scope of the macro definition in the C language standard is, starting at the defined position, ending at its current scope, with only two scopes, that is, the block scope (a pair of {} curly braces) and the end of the entire file, and Secondly, the macro-defined variable belongs to the current file only. Other files cannot access the macro definition variable without including the file with the macro definition, note that even if it is two corresponding header files and source files, they are two separate files (such as A.H and A.cpp).
Of course, some compilers extend the scope of the macro definition, that is, regardless of where the macro definition starts, its scope is the entire file, but this is the compiler implementation principle, not the C language standard, about the language standard and compiler implementation principle is different You can view the blog post about a little understanding of programming languages.
How to understand that the macro definition scope belongs to the current file only. The first example is very simple, a header file A.h, and a source file A.cpp, with each file as follows:
A.h header File
#define B 1;
A.cpp source file, and does not contain A.H header file
void Fun ()
{
int a = 1 + b; Identifier B} not defined
The second example is to avoid a duplicate reference to the header file of the macro definition #ifndef ... #define ... #endif为例, first understand what it means to avoid duplicate references to header files. in fact, "repeated reference" refers to a header file in the same CPP file is include several times, this error is often due to the include caused by nested nesting. For example: There is a a.h file # include "C.h" and at this time b.cpp file import # include "A.h" and # include "C.h" at this time will cause c.h duplicate reference, this time, in the duplicate reference header file using #ifndef ... #define ... #endif是非常有必要的. how to understand it.
First, the source code needs to be preprocessed (that is, precompiled) before compiling, and what is precompiled. All I know is that the header file expansion, macro definition substitution , and so on, for the above example, the B.cpp file imports the # include "A.h" and the # include "C.h" two header files, if you use #ifndef in the header file C.h ... #define ... #endif宏定义格式 (usually at the beginning of a header file), That in the preprocessing B.cpp file, the first A.H header file to expand, because A.h contains c.h header file, so again, this time c.h header file inside the macro definition is equivalent to the b.cpp file inside the definition, its scope is the entire B.cpp file, in the next b.cpp part can be To use or judge the macro definition. After the A.H header file is expanded, because B.cpp also contains the c.h header file, it needs to be expanded again, during this expansion, because the B.cpp file already has the C.H header file macro definition, so at the beginning of the expansion of the decision is false, so the compiler avoids the C , the H header file is expanded. C.h, a.h header files and b.cpp source files are as follows:
C.h header file
#ifndef c_h
#define
The C_h//c.h file needs to provide the interface declaration
//Remember that the header file is declared partially
void Fun_c ();
#endif
A.h header file
#ifndef a_h
#define A_H
#include "c.h"
//a.h file required to provide the interface declaration
Void fun_a ();
#endif
B.cpp file
#include "a.h"
#include "c.h"
//Call a.h and c.h in function
int mian ()
{
fun_c ();
Fun_a ();
}
The above code in the VS2010 editor and no error, and the operation is not a problem, but in the run line need to implement Fun_c () and fun_a () two functions. File B.cpp may become after preprocessing (pseudo-code, not the true output code of the preprocessor)
B.cpp after preprocessing file
/*********************************
#include "a.h" replace start
******************************* /
#define A_H
//#include "c.h"// contains c.h file, continue to replace
#define C_h
void Fun_c ();
void Fun_a ();
/*********************************
#include "a.h" replace complete
**********************************/
/*****
once again, # include "c.h" replace start
**********************************/
//# Include "C.h"
#ifndef c_h //This is a false judgment, because the macro a_h
/*********** The following two lines of code are not replaced *******************/
//#define C_H
//void fun_c ();
#endif
/*********************************
Another # include "C.h" replace end, you can see, and do not add the Fun_c () function's declaration code again
///
call a.h and c.h in function
int mian ()
{
fun_c ();
Fun_a ();
}
If the above code is not enough to let you understand that the scope of the macro definition is only within the scope of the current file, then in the case of a negative argument against this example, the second example above #ifndef ... #define ... endif use is to avoid in the same file (whether CPP or H file) contains a single end of the file, that is, the first header file contains will be expanded, followed by the inclusion of the first to make a macro judgment, the success of the decision is included, but the premise of macro judgment is that the macro is already in the current file, For example, the B.cpp file in the example above, through # include "A.h", where a.h and include "c.h",
So when b.cpp contains the A.H header file, it has already put the two macros of A_h and c_h into the scope of this file, doesn't it mean that the scope of the macro only belongs to its own file? If this is not the case, why the B.cpp file cannot directly judge the A_h and C_h macros, but must first include two header files (see the first example).
Iii. Summary
The scope of a macro definition in the C language standard is to start from the defined position to the end of its current scope, that is, the macro definition belongs to the current file only, and other files cannot use this macro definition if they are not included in the file by # include.