g++ issue

Sep 7, 2010 at 8:47pm
Hey there,

I'm trying to compile the following "project" of 2 source files and one header using g++:
Source: MyStack.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef MYSTACK_H
#define MYSTACK_H

template <typename T>
class MyStack {
public:
	MyStack(int = 10);

	~MyStack();

	bool push(const T&);

	bool pop(T&);

	bool isEmpty() const;

	bool isFull() const;

private:
	int size;
	int topIndex;
	T *top;
};

#endif 


Source: MyStack.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "MyStack.h"

template <typename T>
MyStack<T>::MyStack(int size) {
	this->top 		 = new T[(size > 0) ? size : 10];
	this->size		 = size;
	this->topIndex	 = -1;
}

template <typename T>
MyStack<T>::~MyStack() {
	delete[] this->top;
}

template <typename T>
bool MyStack<T>::push(const T &item) {
	if(this->isFull()) {
		T *newStack = new T[(this->size *= 2)];
		
		for(int i = 0;i < this->size;i++) {
			newStack[i] = this->top[i];
		}

		delete[] this->top;
		this->top = newStack;
	}

	this->top[++this->topIndex] = item;

	return true;
}

template <typename T>
bool MyStack<T>::pop(T &item) {
	if(this->isEmpty()) {
		item = this->top[this->topIndex--];

		return true;
	}

	return false;
}

template <typename T>
bool MyStack<T>::isEmpty() const {
	return this->topIndex == -1;
}

template <typename T>
bool MyStack<T>::isFull() const {
	return this->topIndex == this->size;
}


Source: Main.cpp
1
2
3
4
5
6
7
8
9
10
#include "MyStack.h"
#include <iostream>
using namespace std;

int main() {
	MyStack<int> intStack(3);
	int intValue;

	return 0;
}


and I'm getting the following linker error:
1
2
3
4
5
$ g++ -o MyStack Main.cpp MyStack.cpp
/tmp/ccnksMQn.o: In function `main':
Main.cpp:(.text+0x16): undefined reference to `MyStack<int>::MyStack(int)'
Main.cpp:(.text+0x27): undefined reference to `MyStack<int>::~MyStack()'
collect2: ld returned 1 exit status 


Does someone see what did I do wrong?
Sep 7, 2010 at 8:54pm
closed account (1yR4jE8b)
Put your code for MyStack.cpp into the header file.
Sep 7, 2010 at 8:59pm
Is it the only way to solve this issue?
Actually I was fighting to find a way I didn't have to combine both of them in a single file.
Sep 7, 2010 at 9:03pm
You can rename MyStack.cpp to have an extension that the compiler won't compile automatically and #include it at the end of the header if you want to keep it in another file
Sep 7, 2010 at 9:05pm
Is it a kind of issue with templates? Because I can normally compile any other kind of code this way.
Sep 7, 2010 at 9:09pm
Yes
Sep 7, 2010 at 9:17pm
Good to know. Thank you Bazzy.
Sep 7, 2010 at 9:20pm
closed account (1yR4jE8b)
Let me and try and explain the reason this happens:

The compiler only generates code for template classes/functions when they are called explicitly. So when you try to compile your MyStack.cpp file, the compiler doesn't see any calls to the functions so it simply ignores the definitions and generates an empty object file.

When you try to link that object file with your main.cpp file, the function definitions were not compiled so the linker cannot link the calls to function code. Hence the undefined reference errors from the linker.

This is why the definitions for template code must be in the header files.
Topic archived. No new replies allowed.