1

My code is:

test.cpp

#include<iostream>
#include<boost/bind.hpp>
#include "extern.h"
using namespace std;
using namespace boost;
int fun(int x,int y){return x+y;}
/*
 *void add(int &m,int &n);
 */
int main(){
    int m=1;int n=2;
    cout << m << "  "<< n << endl;
    add(m,n);
    cout << m << "  "<< n << endl;
    return 0;

}

extern.h:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;
void add(int &n,int &m);

extern.cpp:

#include<iostream>
#include<boost/bind.hpp>
using namespace std;
using namespace boost;

extern int m;
extern int n;

void add(int &n,int &m) {
    n = n+1;
    m = m+1;
}

When I compile it with

g++ -Wall -o test test.cpp

It turns out to be:

/tmp/ccMHVRNo.o: In function `main':
test.cpp:(.text+0x7b): undefined reference to `add(int&, int&)'
collect2: ld returned 1 exit status

But when I compile it with:

g++ -Wall -o test test.cpp extern.cpp

It works well:

$ ./test
1  2
2  3

So the reason is that test.cpp can't find the implementation of the add() function.

But I have added extern.h to test.cpp, why does it still say "undefined reference to add(int&, int&)"?

Paul Roub
  • 36,322
  • 27
  • 84
  • 93
kuafu
  • 1,466
  • 5
  • 17
  • 28
  • add `#include "extern.h"` to extern.cpp – Daboyzuk Jun 06 '13 at 14:56
  • Please don't `using namespace std;` or `boost` in a header file. http://stackoverflow.com/questions/1452721 – aschepler Jun 06 '13 at 14:58
  • @aschepler Those comments are less useful than the 'don't parse HTML with regex' ones that come up all the time. It's a bad practice, but we can safely assume that this is simply an example used for brevity. – Richard J. Ross III Jun 06 '13 at 14:59
  • I wouldn't have said anything if it was just in the *.cpp files. In this example, there's no reason for the header to have any `using` statements at all (or `#include`s, for that matter). – aschepler Jun 06 '13 at 15:03
  • aschepler,yeah ,you are right, this file is just modifed from extern.cpp,so I didn't delete the #include s. so after I add "extern.h" to extern.cpp,it didn't solve the problem. – kuafu Jun 06 '13 at 15:05

3 Answers3

3

The implementation of the function void add(int&,int&) is in the source file extern.cpp. The compiler can't know that this files is related to the program until you tell it.

You must specify all source files at the command line:

g++ -Wall -o test test.cpp extern.cpp

If you want to avoid compiling of all source files you can also specify the already compiled object file:

g++ -Wall -o test test.cpp extern.o

When you don't want to think every time what commands you need to compile you should use make and create an Makefile with rules that define how the target is build. with the makefile you can just start

make

and get the result.

harper
  • 13,345
  • 8
  • 56
  • 105
3

The header file extern.h only tells your program how the prototype of the function is made. The linker needs the actual implementation of the function, so it looks for the code add(int&,int&) references to, and it cannot find it unless you give to the compiler all the files it needs (in this case, extern.cpp is the file the linker needs when looking for the add function).

blue
  • 2,683
  • 19
  • 29
  • so I should tell linker about the implememtation of the function. – kuafu Jun 06 '13 at 14:55
  • you just need to pass the files containing the implementation of the functions you're using to the compiler. you need to pass `extern.cpp` otherwise the linker (which is summoned by `g++`) won't find the implementation of the `add` function anywhere. – blue Jun 06 '13 at 14:59
  • I think add #include "extern.h" to extern.cpp should work,but it's not – kuafu Jun 06 '13 at 15:03
  • no, including `extern.h` in `extern.cpp` only copies _word by word_ what's written in `extern.h` inside `extern.cpp`, at the point you included it, and it's a preprocessor directive, so it's executed before compilation starts. I suggest you look at some tutorials or questions on this site about how compilation with multiple files works. – blue Jun 06 '13 at 15:06
  • yeah,it seems I have big misunderstand of multiple files program. :-( – kuafu Jun 06 '13 at 15:08
  • so the solution is to add exter.cpp to compiler or write a makefile.right? – kuafu Jun 06 '13 at 15:13
  • short answer: yes. you need to understand what the compiler does and what's happening during compilation if you want a proper answer. – blue Jun 06 '13 at 15:15
1

This is the usual formula:

g++ -Wall -c test.cpp
g++ -Wall -c extern.cpp
g++ -o test test.o extern.o

There are one-liners, but those don't scale so well to larger projects.

ams
  • 24,923
  • 4
  • 54
  • 75