0

Working on a program where we must build a class for a stack and use it to check if strings are palindromes. Compiler is complaining about an undefined reference to the member functions in class Stack. I am not sure what I am doing wrong, as I believe I am using the exact same syntax as in the past. The files for the class are Stack02.h, Stack02.cpp, and p02.cpp is the main file for the program.

From Stack02.h

    class Stack 
    {
int size;
int tos;
char* S;

public:
    Stack(int sz=100);      //Constructor
    ~Stack();                   //Deconstructor
    bool isFull(void);          
    bool isEmpty(void); 
    void Push(char v);
    char Pop(void);
    };

From Stack02.cpp:

    #include "Stack02.h"
        using namespace std;

        //Exception handling for stacks 
        struct StackException 
        {
            StackException{char* m}
            {
                cout << endl << "I am the Stack and I am " << m << "." << endl;
            }
        };

        Stack::Stack(int sz):size(sz),tos(-1){S= new char[size]};       //Constructor
        Stack::~Stack(){if(S) delete[] S;}                  //Deconstructor

        bool Stack::isFull(void)
        {
            return tos >= size - 1;
        }       //Is the stack full?

        bool Stack::isEmpty(void) 
        {
            return tos < 0;
        }

        void Stack::Push(char v)
        {
            if(isFull) throw StackException("full");
            S[++tos] = c;
        }

        char Stack::Pop(void)
        {
            if(isEmpty) throw StackException("empty");
            return S[tos--];
        }

The function the compiler is complaining about from p02.cpp:

    bool IsPalindrome(string& c) 
    {
Stack s;
for (int a = 0; a < c.length(); a++) s.Push(c[a]);

for (int a = 0; !s.isEmpty() ;a < c.length())
{
    if (c[a] !=s.Pop()) return false;
}

//can use default return value to check how output looks.
    }

The makefile:

    #------------------------------------------------
    #Object files
    #------------------------------------------------
    obj     =       p02.o Stack02.o
    #------------------------------------------------
    #Link object files into executable file p02
    #------------------------------------------------
     p02:            ${obj}
                     g++ -o p02 ${obj} -lm
    #------------------------------------------------
    #Compile p02.cpp that exercises class Stack
    #------------------------------------------------
    p02.o           p02.cpp Stack02.h
                    g++ -g -c p02.cpp
    #------------------------------------------------
    #Compile Stack02.cpp that implements class Stack
    #------------------------------------------------
    Stack02.o       Stack02.cpp Stack02.h
                    g++ -g -c Stack02.cpp

The compiler's complaints:

tt054@cs:~$ make p02
g++     p02.cpp   -o p02
/tmp/ccYDuT0W.o: In function `IsPalindrome(std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)':
p02.cpp:(.text+0x1c): undefined reference to `Stack::Stack(int)'
p02.cpp:(.text+0x4e): undefined reference to `Stack::Push(char)'
p02.cpp:(.text+0x9b): undefined reference to `Stack::Pop()'
p02.cpp:(.text+0xc9): undefined reference to `Stack::isEmpty()'
p02.cpp:(.text+0xe1): undefined reference to `Stack::~Stack()'
p02.cpp:(.text+0xfc): undefined reference to `Stack::~Stack()'
collect2: ld returned 1 exit status
make: *** [p02] Error 1
Victoria Potvin
  • 127
  • 1
  • 11
  • 3
    You need to compile Stack02.cpp as part of your project. Are you doing this? – simonc Jan 29 '14 at 17:27
  • Your makefile doesn't contain a rule specifying that `p02` depends on `p02.cpp` and `Stack02.cpp`. You'll need to add one, or build it yourself with `g++ p02.cpp Stack02.cpp -o p02`. – Mike Seymour Jan 29 '14 at 17:28
  • Since when is defining constructors using `StackException{char* m}` valid code?? 0_o – David G Jan 29 '14 at 17:29
  • @0x499602D2: It isn't; but there's no error (yet) since nothing is trying to compile it. – Mike Seymour Jan 29 '14 at 17:29
  • Ok so definitely the makefile is my problem as I can compile with g++ myself just fine. However we are required to compile with a makefile. What have I done wrong with the makefile that it is not included Stack02.cpp? – Victoria Potvin Jan 29 '14 at 21:27
  • I *believe* this is a one-character typo: in the line `p02.o p02.cpp Stack02.h` there needs to be a colon after the `po2.o`. You may also need to remove the leading space on the `po2: ${obj}` line; I can't remember if that matters. I think this is the problem because I observe that you typed `make p02` and Make ignored your rule for building `p02` from `${obj}`, which suggests that there is something wrong with that rule. Also, after many years of writing Makefiles, the absence of a colon on a dependency-definition line jumps out at me; this is something you must learn to see, too. – zwol Jul 06 '14 at 16:18

1 Answers1

3

You're including the header file, but not building and linking the stack implementation. Try

g++ Stack02.cpp p02.cpp

Or replace g++ with whatever compiler you are using.

Sean
  • 60,939
  • 11
  • 97
  • 136