Trevor Johnson
Trevor Johnson

Reputation: 57

Makefile refuses to work

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

Upvotes: 1

Views: 120

Answers (3)

user48956
user48956

Reputation: 15810

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

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

}; 

Upvotes: 0

Grigory Rechistov
Grigory Rechistov

Reputation: 2224

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

Upvotes: 1

Mike van Dyke
Mike van Dyke

Reputation: 2868

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()

Upvotes: 0

Related Questions