c++ undefined symbol when compiling

46,619

Solution 1

The message you are getting actually comes from the linker, not from the compiler.

One of your member functions, bool Tree::inTree(int index);, is correctly declared and defined as a const member function:

 // Declaration in tree.h
 bool inTree(int index) const;

 // Definition in tree.cc
 bool Tree::inTree(int k) const
 //                       ^^^^^

However, in tree.h you also define this non-const overload of inTree():

// Declaration in tree.h, definition (supposedly) nowhere
bool Tree::inTree(int k)

For which no definition is provided. This is what the linker complains about.

Solution 2

Here is your error:

bool Tree::inTree(int k) const
{
 return locate(k,root) != NULL;
}

in your .h you define

bool inTree(int);

This is a difference!

Share:
46,619
LucienK
Author by

LucienK

Updated on March 19, 2020

Comments

  • LucienK
    LucienK about 4 years

    FIXED: had the method twice in the header file

    I get the following error when trying to compile my project

    % make
    g++ -o p4 testTree.o tree.o node.o check.o
    Undefined                       first referenced
     symbol                             in file
    Tree::inTree(int)                   tree.o
    ld: fatal: Symbol referencing errors. No output written to p4
    collect2: ld returned 1 exit status
    *** Error code 1
    make: Fatal error: Command failed for target `p4'
    

    Makefile

    p4: testTree.o tree.o node.o check.o
        g++ -o p4 testTree.o tree.o node.o check.o
    testTree.o: testTree.cc tree.h node.h check.h
        g++ -c -Wall -Werror testTree.cc
    
    tree.o: tree.h tree.cc node.h check.h
        g++ -c -Wall -Werror tree.cc
    node.o: node.h node.cc check.h
        g++ -c -Wall -Werror node.cc
    check.o: check.h check.cc
        g++ -c -Wall -Werror check.cc
    clean:
        rm -f *~ *.o p4
    

    Relevant code from tree.cc and tree.h:

    tree.cc

    ...
    bool Tree::inTree(int k) const
    {
         return locate(k,root) != NULL;
    }
    ...
    

    tree.h

    #ifndef TREE_H
    #define TREE_H
    
    #include "node.h"
    #include "check.h"
    using namespace std;
    class Tree
    {
      private:
        Node *root;
      public:
        Tree();
        Tree(const Tree & t);
        const Tree & operator=(const Tree &t);
        friend ostream & operator<<(ostream &out, const Tree &t);
        bool inTree(int k) const;
        double & operator[](int k);
        double & operator[](int k) const;
        ~Tree();
        bool inTree(int index);
      private:
        Node * locate(int k, Node *rt) const;
        ostream & display(ostream &out, Node *r, int dir=Node::L) const;
        void add(int k, Node*&r);
        void kill(Node *&rt);
        void copy(Node *rt, Node *&newRt);
    };
    #endif
    

    I get the feeling that it's something really simple, but I can't seem to figure it out.

  • LucienK
    LucienK about 11 years
    I had it declared twice, once with (int k), once with (int index). Thanks for the help.
  • Andy Prowl
    Andy Prowl about 11 years
    @Dazedy: The problem is not that you declared it twice with different argument names. Argument names are irrelevant. The problem is that in one case you used the const qualifier, and in the other you didn't.
  • LucienK
    LucienK about 11 years
    huh. so without that const, would it just overload depending on the variable name, rather than just the number/type of parameters?
  • Andy Prowl
    Andy Prowl about 11 years
    @Dazedy: No, you would have two declarations of the exact same member function - and the compiler would reject it. Parameter names are irrelevant, only parameter types determine a function's signature.