Define variables in the C header file and variables in the C Language
I recently looked at a PHP extension source code and encountered a problem during compilation:
ld: 1 duplicate symbol for architecture x86_64
After carefully reading the source code, we found that the definition of global variables appeared in the header file.
ZEND_DECLARE_MODULE_GLOBALS(xx)
Easy to understand
// t1.h#ifndef T1_H#define T1_Hint a = 0;#endif//------------------//t1.c#include "t1.h"#include "t2.h"int main(){ return 0;}//-----------------//t2.h#include "t1.h"//empty//----------------//t2.c#include "t2.h"//empty//-------
So the first question is: # Should the ifndef macro prevent multiple definitions?
Answer: Yes. However, it is in a single compilation unit (wiki translation unit ).
We know that a complete compilation process goes through
One. c--> PREPROCESSOR->Tmp. c (temporary)-> COMPILER->One. obj-> LINKER->One.exe
In the pre-compilation phase, the include file is expanded. We use the cc-E command to view the pre-compilation result of t1.c:
➜ t cc -E t1.c # 1 "t1.c"# 1 "<built-in>" 1# 1 "<built-in>" 3# 321 "<built-in>" 3# 1 "<command line>" 1# 1 "<built-in>" 2# 1 "t1.c" 2# 1 "./t1.h" 1int a = 0;# 3 "t1.c" 2# 1 "./t2.h" 1# 4 "t1.c" 2int main(void){ return 0;}
The compiler expands t1.h. We can see the definition of.
In the pre-compilation result of t2.c, we also see the expanded definition of:
➜ t cc -E t2.c # 1 "t2.c"# 1 "<built-in>" 1# 1 "<built-in>" 3# 321 "<built-in>" 3# 1 "<command line>" 1# 1 "<built-in>" 2# 1 "t2.c" 2# 1 "./t2.h" 1# 1 "./t1.h" 1int a = 0;# 2 "./t2.h" 2# 2 "t2.c" 2
So why does Shenma # ifdef (include guards) play a role in preventing redefinition?
The reason is that include guards only works in the same compilation unit (the compilation process of a c file and an include file). The two compilation units are separated during the compilation process, so I cannot notice the # ifdefine content in another one.
t1.c -> t1.s -> t2.o \ *-> - t.otu /t2.c -> t2.s -> t2.o
Therefore, the define variable should not be included in the header file, but should only be declare.
What if I want it?
If it is a function, someone provides this method to add the inline or static keyword. Or someone directly does this:
#ifdef DEFINE_GLOBALS#define EXTERN#else#define EXTERN extern#endifEXTERN int global1;EXTERN int global2;
Back to the initial issue, variables cannot be defined in the header file, and I have not seen any special macro definition solution. How does one solve this problem? Is it in the compilation phase?
And wait for the next section...