Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

GeeYouEye

macrumors 68000
Original poster
Dec 9, 2001
1,669
10
State of Denial
Hopefully someone can figure out what's going on... I sure can't...

in main.cpp:
Code:
#include <iostream>
#include <fstream>
#include <string>
#include "symtab.h"
#include "OpCode.h"
using namespace std;
int main(int argc, char **argv)
{
...
}

in OpCode.h:
Code:
#ifndef OPCODE_H
#define OPCODE_H
#include <string>

using namespace std;
class OpCode
{
public: 
	OpCode(string mnem);
	OpCode(string mnem, char hex, int bytes, string otherInfo);
	string getMnem() { return iMnem;}
	char getHex() {return iHex;}
	int getBytes() {return length;}
	string getOtherInfo() {return info;}
private:
	string iMnem;
	char iHex;
	int length;
	string info;
};
#endif

in OpCode.cpp
Code:
OpCode::OpCode(string mnem){iMnem = mnem;}
OpCode::OpCode(string mnem, char hex, int bytes, string otherInfo)
{
	iMnem = mnem;
	iHex = hex;
	length = bytes;
	info = otherInfo;
}
Note that all the other functions in OpCode are defined inline.

in symtab.h (where I suspect I'm missing something):
Code:
#ifndef SYMTAB_H
#define SYMTAB_H

#include <string>
using namespace std;
template <class AT>
class Item {
    public:
        Item(string s);
        string getname(); // returns the name
        AT attr; // attributes other than name
    private:
        string name;
    };

template <class AT>
struct Node{
    Item<AT> * info;
    Node<AT> * link;};

template <class AT>
class SymTab {
    public:
        SymTab(); //initializes to the empty table
        Item<AT> * find(string s); //returns Item pointer or null
        Item<AT> * insert(string s); //inserts if necessary and 
                                     //returns Item pointer
        ~SymTab(); //This seems almost more necessary than the constructor

    private:
        Node<AT> hashTab[137]; 
        int hash(string s);
        Node<AT> * cons(Item<AT> * x, Node<AT> * y); //returns a new list node
                           // with x in the info field and y in the link field
    };

#endif

and in symtab.cpp
Code:
#include "symtab.h"
template <class AT>
Item<AT>::Item(string s)
{
    name = s;
}
template <class AT>
string Item<AT>::getname() { return name;} // returns the name

template <class AT>
SymTab<AT>::SymTab()
{
}

template <class AT>
Item<AT> * SymTab<AT>::find(string s)
{
...
}

template <class AT>
Item<AT> * SymTab<AT>::insert(string s)
{
...
}

template <class AT>
int SymTab<AT>::hash(string s)
{
...
}

template <class AT>
Node<AT> * SymTab<AT>::cons(Item<AT> *x, Node<AT> * y)
{
    Node<AT> * ret = new Node<AT>;
    ret->info = x;
    ret->link = y;
    return ret;
}

template <class AT>
SymTab<AT>::~SymTab()
{
...
}

It compiles fine, but the linker is choking somewhere. Specifically, I get
/usr/bin/ld said:
Undefined symbols:
Item<OpCode>::getname()
SymTab<OpCode>::find(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)
SymTab<OpCode>::insert(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)
SymTab<OpCode>::SymTab()
SymTab<OpCode>::~SymTab()
collect2: ld returned 1 exit status
Everything's defined (although the SymTab constructor doesn't do anything since the only actual data is a fixed array), everything's properly included as far as I can tell... this is driving me nuts. Someone tell me I'm misspelling something somewhere.
 

zimv20

macrumors 601
Jul 18, 2002
4,402
11
toronto
been a while since i've done this stuff, but...

are you calling the linker properly? it looks like it doesn't know about OpCode.o and symtab.o.

also, from the coding sign, i guess i'm a little suprised that you have template classes that don't have constructors taking AT as an argument.
 

iSee

macrumors 68040
Oct 25, 2004
3,540
272
All template function definitions need to be in in the header file, either with the class delcaration or inlined after the class declaration.

That is, everything in symtab.cpp needs to be put in symtab.h, either embedded in the class declaration or inline'd afterwards.

Why? In order for a template class to be instantiated for a particular type, ALL the code needs to be available to the compiler. At their heart, templates are automated copy, seatch and replace engines. When you use SymTab<OpCode>, the compiler basically copies everything to do with SymTab from the header file and replaces AT with OpCode and then compiles it. It doesn't have access to the code in symtab.cpp, because that isn't included.
 

GeeYouEye

macrumors 68000
Original poster
Dec 9, 2001
1,669
10
State of Denial
Yep, it was a combination of splitting it into two files (one bit of C++ I'd forgotten) and the templated constructor issue. Now to just get the rest of this code working...
 

GeeYouEye

macrumors 68000
Original poster
Dec 9, 2001
1,669
10
State of Denial
And on that note, I'm trying to read in a hex value from a file. currently, I'm using ifstream infile; infile.open("file.txt"); infile >> hex >> myChar; and the 18 is only being read as 1, with the 8 being parsed later and leading to all sorts of screwups.

Dang how I wish I could just use the Foundation framework.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.