(Apologies if it is simple, and I am simply being blind.)
main.cpp:
#include "a.h"
int main()
{
x = 4 ;
}
a.h:
extern int x ;
(For some reason this code worked during the first compilation, but not the second one.
Side question: Occasionally I have problems where I need to compile a code twice for it to work. Do I have compiler issues?)
As you know, building a C or C++ program involves three steps: preprocessing, compiling and linking. Here is a simple, non-technical description of what happens.
The preprocessor will replace the #include "a.h"
with the verbatim contents of the file a.h. This results in
extern int x;
int main()
{
x = 4;
}
The compiler processes the output of the preprocessor. The extern int x;
is a declaration only, not a definition. It tells the compiler that it can trust that somewhere else space is reserved for a variable called x
of type int
. (extern x
means that x
has so-called external linkage.) The compiler generates code to set this variable to 4, but marks the code to ask the linker to fill in the actual location of x
once the linker has determined where it is defined.
The linker processes the object file generated by the compiler in the previous step. It looks for an actual definition of x
but finds none (x
was only declared but never defined) and issues an undefined symbol error.
If you want to see extern
in action, simply create a third file, say b.cpp
:
// b.cpp
int x;
If you now build a program consisting of main.cpp
and b.cpp
, the linker error disappears. b.cpp
defines x
, so the linker will pick up this definition and fill in the location of x in the placeholder code generated by the compilation of main.cpp
where it gets set to 4.
As for the side question: I think your issue where compilation sometimes succeeds and sometimes not is likely due to some mistake on the operator's part :-)