Search code examples
externundefined-reference

Can't locate the undefined reference to an extern variable (dev c++)


(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?)


Solution

  • 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.

    1. Preprocessing

    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;
    }
    
    1. Compiling

    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.

    1. Linking

    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 :-)