2

I have three files:

my.cpp

#include "my.h"
#include <iostream> 

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

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

my.h

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

use.cpp

#include "my.h"

int main(int argc, char *argv[]) {
    foo = 7;
    print_foo();
    print(99);
    return 0;
}

Now when I run g++ my.cpp use.cpp I get the error

/usr/bin/ld: /tmp/ccUKJUlZ.o: in function `print_foo()':
my.cpp:(.text+0x6): undefined reference to `foo'
/usr/bin/ld: /tmp/ccN0mIhY.o: in function `main':
use.cpp:(.text+0x11): undefined reference to `foo'
collect2: error: ld returned 1 exit status

Additionally, if I run g++ -c my.cpp everything goes alright, but, if I then run g++ my.o use.cpp I get the same error.

AviouslyAK
  • 107
  • 5

1 Answers1

1

You never actually define a variable foo - in both use.cpp and my.cpp, you use foo, and in my.h you declare it as an extern.

See the beginning of this response for more information on declaring vs. defining. You may think that your problem would be solved if you added a type in front of your foo = 7 line in use.cpp; however, what you also need to do is make foo a global variable instead of a local one (which it is when you declare it simply within main), as extern will only "find" variables that have global scope. You can make a variable global by declaring it outside of any function (side note - you should only use global variables when you absolutely have to).

Therefore, you could solve your problem by changing your use.cpp to the following:

#include "my.h"

int foo = 7;
int main(int argc, char *argv[]) {
    print_foo();
    print(99);
    return 0;
}
thisisbenmanley
  • 386
  • 2
  • 9
  • When I define foo in the global scope with ```int foo = 7``` why do I need to put a type in front of it when I declared its type in **my.h**? – AviouslyAK Nov 30 '19 at 02:27
  • 1
    When you define any variable (in any scope), like with `int foo = 7`, that's the line of code that triggers the compiler to allocate storage for the variable, so the compiler needs the type to know how much storage to allocate. You still have to mention the type in your `extern` because `extern` is just another form of declaring a variable. Not putting the type in an `extern` is like not putting a type in front of any other declaration you do (for example, you can't just put the line "`bar;`" in place of "`int bar;`") – thisisbenmanley Nov 30 '19 at 02:36