1

I am having some linker errors that I can't for the life of me sort out. I simply have a .h file and a .cc file that will not compile into an executable I won't post all my code except the makefile here:

# Compiler variables
CCFLAGS = -Wall

# Rule to link object code files to create executable file
assignment5.exe: assignment5.cc
        g++ -Wall -g -std=c++11 assignment5.cc assignment5.h  -o assignment5.exe

clean:
        rm assignment5.exe

I have both assignment5.h and assignment5.cc in the same directory and when running 'make' I get this error:

assignment5.cc:113: undefined reference to `binTree::inorder(void (*)(int))'
assignment5.cc:116: undefined reference to `binTree::preorder(void (*)(int))'
assignment5.cc:119: undefined reference to `binTree::postorder(void (*)(int))'

If anyone can help me I'd be eternally grateful EDIT: Code for those who asked .h File:

#ifndef ASSIGNMENT5
#define ASSIGNMENT5
class binTree; class BST;
 class Node {
 public:
    // the value
    int data;

    // the left and right
    Node * left;
    Node * right;

    // the constructor
    Node(int data)
    {
        // set the data
        this->data = data;

        // set left and right to null
        this->right = nullptr;
        this->left = nullptr;
    }
};
class binTree
{
 public:
    binTree();
    virtual void insert( int ); //Inserts a node into the tree
    unsigned height() const; //Returns height of the tree
    unsigned size() const; //Returns size of the tree
    void inorder( void(*)(int) ); //Inorder traversal of tree
    void preorder( void(*)(int) ); //Preorder traversal
    void postorder( void(*)(int) ); //Postorder traversal

protected:
    Node* root; //root of the tree

private:
    void insert( Node*&, int ); //Private version of insert()
    unsigned height( Node* ) const; //Private version of height
    unsigned size( Node* ) const; //Private version of size()
    void inorder( Node*, void(*)(int) ); //Private version of inorder()
    void preorder( Node*, void(*)(int) ); //Private version of preorder()
    void postorder( Node*, void(*)(int) ); //Private version of postorder()

};
#endif

.cc File:

#include "assignment5.h"
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
using namespace std;

const int MAX_SIZE = 40;
const int MAX_COUNT = 40;
const int WIDTH = 5;
const int ROW_SIZE = 8;
int mcount = 0;
int rcount = 0;

void display(int d)
{
    if (mcount < MAX_COUNT) {
        cout << setw(WIDTH) << d;
        mcount++;
        rcount++;
        if (rcount == ROW_SIZE) {
            cout << endl;
            rcount = 0;
        }
    }
}

binTree::binTree()
{
    // set the root to null pointer
    root = nullptr;
}

void binTree::insert( int v )         //Inserts a node into the tree
{
    // insert this value into the root
    insert(root,v);
}

unsigned binTree::height() const            //Returns height of the tree
{
    // return the height of this tree
    return height(root);
}
unsigned binTree::size() const            //Returns size of the tree
{
    // return the size
    return size(root);
}
void binTree::inorder( void(*)(int) p )      //Inorder traversal of tree
{
    // use the local inorder
    inorder(root, p);
}
void binTree::preorder( void(*)(int) p )      //Preorder traversal
{
    // use the local preorder
   inorder(root, p);
}
void binTree::postorder( void(*)(int) p )    //Postorder traversal
{
    // use the local inorder
    postorder(root, p);
}

void binTree::insert( Node*& node, int n )        //Private version of insert()
{
    // if this is null, create new node
    if( node == nullptr )
    {
        // create new node
        node = new Node(n);
    }

    // if node is less or more
    if( n < node->data )
    {
        // go left
        insert(node->left,n);
    }
    else if( n > node->data )
    {
        // go right
        insert(node->right, n);
    }
}

unsigned binTree::height( Node* node ) const    //Private version of height
{
    // if this is null, return 0
    if( node == nullptr )
        return 0;

    // left height and right height
    unsigned leftHeight = 0;
    unsigned rightHeight = 0;

    // check if left height
    if( node->left != nullptr )
        leftHeight = height( node->left );

    // right height
    if( node->right != nullptr )
        rightHeight = height( node->right );

    // return max
    if( leftHeight > rightHeight )
        return leftHeight + 1;
    else
        return rightHeight+1;
}
unsigned binTree::size( Node*  node) const     //Private version of size()
{
    // if this is null
    if( node == nullptr )
        return 0;

    // return size
    return 1 + size(node->left) + size(node->right);
}

#define BINTREE_MAIN
#ifdef BINTREE_MAIN
int main() {
    vector<int> v(MAX_SIZE);
    for (int i=1; i<MAX_SIZE; i++)
        v[i] = i;
    random_shuffle( v.begin(), v.end());

    binTree bt;
    vector<int>::iterator it;
    for (it=v.begin(); it!=v.end(); it++)
        bt.insert( *it );

    cout << "Height: " << bt.height() << endl;
    cout << "Size: " << bt.size() << endl;
    cout << "In order traverse (displaying first " << MAX_COUNT << " numbers): " << endl;
    mcount = rcount = 0;
    bt.inorder( display );
    cout << "\n\nPre order traverse (displaying first " << MAX_COUNT << " numbers): " << endl;
    mcount = rcount = 0;
    bt.preorder( display );
    cout << "\n\nPost order traverse (displaying first " << MAX_COUNT << " numbers): " << endl;
    mcount = rcount = 0;
    bt.postorder( display );

    cout << endl;
    return 0;
}

#endif
  • 2
    Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Passer By Mar 02 '18 at 20:07
  • In what file is `binTree` defined? And are you sure? – Lightness Races in Orbit Mar 02 '18 at 20:13
  • @LightnessRacesinOrbit Its defined in the header – Trevor Johnson Mar 02 '18 at 20:19
  • 1
    When in doubt, enter the compiler command into a command window. Eliminate the `make` utility to narrow the root cause of the issue. – Thomas Matthews Mar 02 '18 at 20:34
  • @ThomasMatthews: They stopped doing that when MC6800 made HCF a real instruction – Lightness Races in Orbit Mar 02 '18 at 20:34
  • 1
    I suspect the `binTree` members are just *declared* in the header -- not defined. The definition is in a library that you need to link against. – G.M. Mar 02 '18 at 20:34
  • You need to link the library in the project settings –  Mar 02 '18 at 20:38
  • @k.Lennartz: There are no project settings; this is a Makefile. The OP is building by hand. – Lightness Races in Orbit Mar 02 '18 at 20:48
  • Ugh, this isn't Windows! You don't conventionally use `.exe` as an extension on Unix because it is cleverer than Windows and it knows what executable files are without being told. Also, you don't normally add header files to your compiler invocation, so remove the `.h` file from the line starting `g++` and add it to the line above because it is a dependency - meaning that you should recompile if it changes. – Mark Setchell Mar 02 '18 at 21:17
  • What have you changed since this code was last working? If the answer is "everything", then you must revert to `HelloWorld` and build up step by careful step. – Beta Mar 02 '18 at 22:56

3 Answers3

1

The Makefile is not (the only one) to blame. Your example is plagued with problems. For starters, it is not a complete example, as a half of methods is not defined, only declared, and there is no main(), even a dummy one, when you are trying to build an executable, not an object file. Such an incomplete example really complicates helping you.

And you seem not telling the whole truth. My g++ invocation breaks even earlier, at this line:

  void inorder( void(*)(int) ); //Inorder traversal of tree
  expected primary-expression before ‘void’

Did you attempt to declare a method which accepts a parameter that is a pointer to a function(int)? You need to understand what is the syntax for that in C++.

Your recipe line in the makefile is also flawed: you do not need to pass header files to a compiler, they are included automatically when you #include them in .cc files. Your build line should be similar to:

 g++ $(CCFLAGS) -g -std=c++11 assignment5.cc -o assignment5.o
Grigory Rechistov
  • 2,104
  • 16
  • 25
0

You haven't implemented the private functions:

void inorder( Node*, void(*)(int) ); //Private version of inorder()
void preorder( Node*, void(*)(int) ); //Private version of preorder()
void postorder( Node*, void(*)(int) ); //Private version of postorder()
Mike van Dyke
  • 2,724
  • 3
  • 16
  • 31
0

You have two bintree classes. Fix that first and report back.

class binTree; class BST;
 class Node {
....
}; 
 ....   
class binTree {

}; 
user48956
  • 14,850
  • 19
  • 93
  • 154