Undefined reference compiling with g++

Asked

Viewed 4,033 times

1

I usually use g++ to compile my code, but now that I’ve started learning template I cannot compile for anything, the following error appears:

g++ -c pilha.cpp pilha-infinita.cpp
g++ pilha.o pilha-infinita.o -o pilha.exe

    pilha-infinita.o: na função `main':
pilha-infinita.cpp:(.text+0x2c): referência indefinida para `pilha<int>::vazio()'
pilha-infinita.cpp:(.text+0x3f): referência indefinida para `pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x69): referência indefinida para `pilha<int>::~pilha()'
pilha-infinita.cpp:(.text+0x8b): referência indefinida para `pilha<int>::~pilha()'
collect2: error: ld returned 1 exit status

Follows the codes of the files stack. h, stack.cpp and infinite.cpp below:

//pile. h

#include <iostream>
#include <stdlib.h>

using namespace std;

template <class T>
class elemento
{
    T dado;
    elemento<T> *prox;
};

template <class T>
class pilha
{
private:
    elemento<T> *top;
public:
    pilha() { top = NULL; }
    bool empilha(T);
    T topo();
    T pop();
    bool vazio();
    ~pilha();

};

//cell.cpp

#include "pilha.h"
#include <stdio.h>
#include <stdlib.h>


template <class T>
pilha<T>::~pilha()
{
    delete [] top;
}

template <class T>
bool pilha<T>::empilha(T x)
{
    if (top==NULL)
    {
        top = new elemento<T>;
        top->dado = x;
        top->prox = NULL;
        return true;
    }
    else
    {
        elemento<T> *aux = new elemento<T>;
        aux->dado = x;
        aux->prox = top;
        top = aux;
        return true;
    }
    return false;
}

template <class T>
T pilha<T>::topo()
{
    if (!vazio())
    {
        return top->dado;
    }
    return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
}

template <class T>
T pilha<T>::pop()
{
    if (vazio())
    {
        return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
    }
    else
    {
        T aux = top->dado;
        top = top->prox;
        return aux;
    }
}

template <class T>
bool pilha<T>::vazio()
{
    return (top==NULL);
}

//infinite cell.cpp

#include <iostream>
#include "pilha.h"

using namespace std;

int main()
{
    pilha<int> p;
    if (!p.vazio())
    {
        cout<<p.topo()<< endl;
    }
    p.empilha(1);
    cout<<p.pop()<< endl;
    p.empilha(2);
    cout<<p.pop()<< endl;
    p.empilha(3);
    cout<<p.pop()<< endl;
    p.empilha(4);
    cout<<p.pop()<< endl;
    p.empilha(5);
    cout<<p.pop()<< endl;
    p.empilha(6);
    p.empilha(7);
    p.empilha(8);
    cout<<p.pop()<< endl;
    p.empilha(9);
    p.empilha(10);
    p.empilha(11);
    p.empilha(12);
    p.empilha(13);
    cout<<p.pop()<< endl;
    p.empilha(14);

    cout<<p.topo()<< endl;

    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    return 0;
}

After entering the public is giving the following errors:

pilha-infinita.o: na função `main':
pilha-infinita.cpp:(.text+0x2c): referência indefinida para `pilha<int>::vazio()'
pilha-infinita.cpp:(.text+0x3f): referência indefinida para `pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x69): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x75): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x9f): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0xab): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0xd5): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0xe1): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x10b): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x117): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x141): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x14d): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x177): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x188): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x199): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1a5): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x1cf): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1e0): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x1f1): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x202): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x213): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x21f): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x249): referência indefinida para `pilha<int>::empilha(int)'
pilha-infinita.cpp:(.text+0x255): referência indefinida para `pilha<int>::topo()'
pilha-infinita.cpp:(.text+0x27a): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x29f): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x2c4): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x2e9): referência indefinida para `pilha<int>::pop()'
pilha-infinita.cpp:(.text+0x30e): referência indefinida para `pilha<int>::pop()'
pilha-infinita.o:pilha-infinita.cpp:(.text+0x333): mais referências indefinidas para seguir `pilha<int>::pop()'
pilha-infinita.o: na função `main':
pilha-infinita.cpp:(.text+0x3a7): referência indefinida para `pilha<int>::~pilha()'
pilha-infinita.cpp:(.text+0x3c9): referência indefinida para `pilha<int>::~pilha()'
collect2: error: ld returned 1 exit status
  • Take a look at [tour]. You can accept an answer if it solved your problem. You can vote on every post on the site as well. Did any help you more? You need something to be improved?

  • 1

    I believe it is because the "stack. h" is already inside the "stack.cpp"...

3 answers

2

Change this:

template <class T>
class elemento {
    public:
        T dado;
        elemento<T> *prox;
};

You cannot access private class data. Remember which classes have their private members by default, unlike the structs.

I believe this may be the problem or at least a problem. It is not the same process but see working in the ideone. And in the repl it.. Also put on the Github for future reference. Without this change did not compile. It is likely that the build failure was failing to linkediting.

#include <iostream>
using namespace std;

template <class T>
class elemento {
    public:
        T dado;
        elemento<T> *prox;
};

template <class T>
class pilha {
private:
    elemento<T> *top;
public:
    pilha() { top = NULL; }
    bool empilha(T);
    T topo();
    T pop();
    bool vazio();
    ~pilha();
};

template <class T>
pilha<T>::~pilha() {
    delete [] top;
}

template <class T>
bool pilha<T>::empilha(T x) {
    if (top == NULL) {
        top = new elemento<T>;
        top->dado = x;
        top->prox = NULL;
        return true;
    } else {
        elemento<T> *aux = new elemento<T>;
        aux->dado = x;
        aux->prox = top;
        top = aux;
        return true;
    }
    return false;
}

template <class T>
T pilha<T>::topo() {
    if (!vazio()) return top->dado;
    return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
}

template <class T>
T pilha<T>::pop() {
    if (vazio()) return -1; //RETORNA -1 QUANDO A PILHA ESTA VAZIA
    else {
        T aux = top->dado;
        top = top->prox;
        return aux;
    }
}

template <class T>
bool pilha<T>::vazio() { return (top==NULL); }

using namespace std;

int main() {
    pilha<int> p;
    if (!p.vazio()) {
        cout<<p.topo()<< endl;
    }
    p.empilha(1);
    cout<<p.pop()<< endl;
    p.empilha(2);
    cout<<p.pop()<< endl;
    p.empilha(3);
    cout<<p.pop()<< endl;
    p.empilha(4);
    cout<<p.pop()<< endl;
    p.empilha(5);
    cout<<p.pop()<< endl;
    p.empilha(6);
    p.empilha(7);
    p.empilha(8);
    cout<<p.pop()<< endl;
    p.empilha(9);
    p.empilha(10);
    p.empilha(11);
    p.empilha(12);
    p.empilha(13);
    cout<<p.pop()<< endl;
    p.empilha(14);
    cout<<p.topo()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
    cout<<p.pop()<< endl;
}
  • I made the modification, but it gave more indefinite reference errors. The strange thing is that when I put the whole code in a file it only works normally.

  • Is there any reason not to do the compilation process completely without the -c? There seems to be nothing wrong with the command line you have placed and the code with this change compiles. But if there are other errors you can show them. Although I don’t know if I’ll be able to help because it doesn’t seem to have much of a secret. It’s a shame I don’t have the compiler to test. I don’t remember if it causes problems but anyway the ideal is to put the #include "pilha.h" after the includes of the system.

  • I entered the errors at the end of the question.. Have a look please.

1

Since this is a class template, you have to put the implementation of the functions in the pilha.h, so that whenever you enter a new object, the compiler knows how to interpret the template and creates a new specific class. This is, pilha<int> and pilha<float> are interpreted as different classes and are created separately by the compiler -> Conclusion, eliminates the pilha.cpp and writes all functions on pilha.h.

As an alternative to placing implementations on pilha.h, can, in the pilha.cpp, do what is called explicit instantiation, and put all the templates you need at the end of the file. For example, if you need batteries to int and float you can write at the end of pilha.cpp:

...
...

template <class T>
bool pilha<T>::vazio()
{
    return (top==NULL);
}

template class pilha<int>;
template class pilha<float>;
etc...

0


I was able to solve the problem by modifying include in the infinite-stack.cpp file.

In place of:

#include "pilha.h"

Placed:

#include "pilha.cpp"

I don’t quite understand why it worked, but it did. Thanks for your help!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.