Search code examples
c++header-filesexternunresolved-externalcompilationunit

Unresolved symbol error


I'm working through exercises from Programming Principles and Practice using Visual Studio 2012. When trying to compile the source code below I'm getting a linker error:

unresolved symbol int foo.

I don't understand why the symbol is unresolved.

my.h

extern int foo;
void print_foo();
void print(int);

my.cpp

#include "my.h"
#include "../../std_lib_facilities.h"

void print_foo()
{
    cout<<foo<<'\n';
}

void print(int i)
{
    cout<<i<<'\n';
}

use.cpp

#include "my.h"

int main(){
    int foo = 7;

    print_foo();
    print(99);
}

Solution

  • extern int foo;
    

    This is a declaration. It tells the compiler "there's going to be an variable called foo of type int in the global namespace defined somewhere".

    int main(){    
        int foo = 7;
        // ...
    }
    

    This defines a local variable foo of type int inside the function main() and initializes it to 7. This local variable is not visible outside of main().

    What you didn't do is actually define foo in the global namespace. To do that, add this line to exactly one of either my.cpp or use.cpp, after the includes:

    int foo;
    

    This defines a variable called foo of type int in the global namespace. (As an object of static storage duration, foo is initialized to zero by default, though you can also provide a different initializer if you want.) The linker should then be able to resolve the reference to the global foo that's in print_foo() when you link the object files together.

    It is very important that you only define foo once, though you can declare it as many times as you want. Doing otherwise violates the One Definition Rule and results in a linker error if you are lucky, and undefined behavior if you are not.