(CROSS-POSTED) Problem with ld/GCC?

Ainsley Pereira marble at linuxfromscratch.org
Thu May 2 14:24:49 PDT 2002

In message <200205021937.g42Jb8I28218 at mailout6.nyroc.rr.com>
          Joe Morris <heartboy at nycap.rr.com> wittered:

> Hey everyone!  I've been trying to write the start of a C++ program, but I
> can't get it to compile.  This same exact code worked on one of the Mac's
> at school, but I can't get it to work on my machine.  I tried GCC-2.95.3
> and 3.0.4, as well as recompiling binutils (I tried both 2.11.2 and 2.12).
> I can't seem to get this to work.  Oddly, if I put the contents of all of the 
> attached files into one large file, it works beautifully.  These are the 
> errors I receive when I break it down into node.h, node.cpp, and main.cpp:
> joe:~/fed/fed$ g++ main.cpp node.cpp
> /tmp/ccnDtzfi.o: In function `main':
> /tmp/ccnDtzfi.o(.text+0x67): undefined reference to `Node<int>::Data(void)'
> collect2: ld returned 1 exit status
> Do you think it is a hardware or software problem?  Would you mind trying
> to compile it on your machines?  Thanks a lot!
> Joe
> -----------------------------------------------
> node.h:
> #ifndef NODE_H
> #define NODE_H
> template<class T>
> class Node{
>      public:
> 	    Node(T data, Node *next, Node *prev):
> 		myData(data), myPrev(prev), myNext(next) {}
>             Node *Next();
>             Node *Prev();
>             T Data();
>      private:
>             T myData;
>             Node *myPrev, *myNext;
> };
> #endif
> ------------------------------------------------------
> node.cpp:
> #include "node.h"
> template <class T>
> Node<T> * Node<T>::Next(){return myNext;}
> template <class T>
> Node<T> * Node<T>::Prev(){return myPrev;}
> template <class T>
> T Node<T>::Data(){return myData;}
> -----------------------------------------------------
> main.cpp
> #include <iostream.h>
> #include "node.h"
> int main(){
>      Node<int> *great=new Node<int>(3,0,0);
>      cout<<great->Data()<<endl;
>      return 0;
> }

This really isn't a C++ support group, but your problem is that to generate the
member template 'Data', the compiler needs to have the

template <class T>
T Node<T>::Data() { return myData; }

in its head when it realises it needs to generate it, so that it knows how.

Those two lines are in your node.cpp file, but it knows it needs a Node<int>
when you tell it that in main.cpp. At this point, it has the contents of
iostream.h and node.h, because you have #included them, but not node.cpp.

For template member functions, put them in the header file. (Not for normal
member functions, or you'll get multiple definitions, but only for templates).
Or, if you're using a compiler that actually supports the 'export' keyword
from the c++ standard, you could use that. But you're not, because hardly any
compilers do (not gcc, not microsoft's latest beta).

In short, stick the contents of node.cpp in node.h and forget about node.cpp.

(PS. Don't use 'iostream.h' - it's non-standard; instead put:
#include <iostream>      // note: no .h
using namespace std;     // or using std::cout; using std::endl; or explicitly
                         // refer to them as std::cout and std::endl everywhere

Hope that helps,

  / Ainsley 'Marble' Pereira / http://www.snowplains.org /
 / Don't drink and drive.
Unsubscribe: send email to listar at linuxfromscratch.org
and put 'unsubscribe blfs-support' in the subject header of the message

More information about the blfs-support mailing list