1

I am currently working on a virtual run time environment program that is at a very early stage, i am prevented from continuing my work due to a linker error when using my makefile, provided below. The error i am receiving is:

g++ controller.o processor.o test.o -o final
controller.o: In function `Controller::run()':
controller.cpp:(.text+0x1e0): undefined reference to
Processor::codeParams(char)'
controller.o: In function `Controller::fetch()':
controller.cpp:(.text+0x290): undefined reference to `Controller::pc'
controller.cpp:(.text+0x299): undefined reference to `Controller::pc'
collect2: error: ld returned 1 exit status
makefile:16: recipe for target 'final' failed
make: *** [final] Error 1

I am unsure as to why i get this error as i thought i had defined these things in the source file corresponding to the header. All files will be given below so that the program can be compiled.

test.cpp:

#include <iostream>
#include <vector>
#include "includes/controller.h"

using namespace std;

int main()
{
    vector<char> prog = {0x0};

    Controller contr(prog);
    cout << "Error Code: " << contr.run() << endl;

    return 0;
}

controller.cpp:

/*
    Author(s):  James Dolan
    File:       controller.cpp
    Build:      0.0.0
    Header:     includes/controller.h
    DoLR:       21:39 11/1/2017

    Todo: n/a
*/



#include "includes/controller.h"


Controller::Controller(vector<char> prog)
{
    printf("Program:");                         //Display program
    for(auto i : program)
    {
        printf("%02X", i);
    }
    printf("\n");

    Controller::program = program;
}

Controller::~Controller ()
{
}

int Controller::run()
{
    bool runFlag = true;
    int errorCode = 0;
    char curCode;
    vector<char> curInstr;
    int paramRef;

    while(runFlag)
    {
        curCode = fetch();
        printf("curCode:%02X\n", curCode);
        curInstr.push_back(curCode);
        paramRef = proc.codeParams(curCode);

        if (paramRef == 0xffff){runFlag = false; continue;}     //Check if shutdown signal was returned, if so shutdown
        printf("opcode good\n");

        for(int i; i<paramRef; i++){curInstr.push_back(fetch());}
    }


    return errorCode;
}

char Controller::fetch()
{
    return program[pc++];                       //Return next instruction then increment the program counter
}

controller.h:

/*
    Author(s):  James Dolan
    File:       controller.h
    Source:     ../controller.cpp
    DoLR:       21:39 11/1/2017

    Todo: n/a
*/


#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <iostream>
#include <vector>
#include <cstdlib>

#include "processor.h"

using namespace std;

class Controller{

    public:
        Controller(vector<char> prog);
        ~Controller();
        int run();

    protected:

    private:
        vector<char> program;
        static int pc;
        char fetch();
        Processor proc();


};

#endif

processor.cpp:

#include "includes/processor.h"

Processor::Processor()
{
}

Processor::~Processor()
{
}

int codeParams(char code)
{

    switch(code)
    {
        case 0x0:                   //Halt
            return 0;
        default:
            printf("[ERROR!] Invalid opcode [%02X]", code);
            return 0xffff;          //Return shutdown signal
    }
}

processor.h:

#ifndef PROCESSOR_H
#define PROCESSOR_H

#include <iostream>
#include <cstdlib>

class Processor{

    public:
        Processor();
        ~Processor();
        int codeParams(char code);

    protected:

    private:

};

#endif

All if any help is appreciated massively as it will help me to continue with my passion of developing a fully fledged open-source virtual runtime enviroment like the java vm, thank you for your time.

  • 1
    You have a couple problems. One is a typo (look at how you define `codeParams` in the cpp file) and the other is a dupe of [this](http://stackoverflow.com/questions/16284629/undefined-reference-to-static-variable-c) – NathanOliver Jan 12 '17 at 17:08

2 Answers2

0

For the member function Processor::codeParams you should define it as:

int Processor::codeParams(char code)
//  ~~~~~~~~~~~
{
  ...
}

Otherwise it's just a normal (non–member) function.

For the static member Controller::pc you should define it outside of the class definition, in controller.cpp.

// Controller.h
class Controller {
    ...
    private:
        static int pc;
};

// controller.cpp
int Controller::pc;
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Place outside the class definition? do you have an example of how this would be implemented? –  Jan 12 '17 at 17:10
  • Thank you very much, i am unable to upvote unfortunately but this has resolved my issue. –  Jan 12 '17 at 17:11
  • @J.Dolan http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – Simon Kraemer Jan 12 '17 at 17:21
0

In Controller.cpp you need a int Controller::pc; or int Controller::pc = 0;

In the header file you declared a static int named pc that exists somewhere. It needs to actually exist in a translation unit somewhere (in this case Controller.cpp) so that when the linker tries to find it... it exists.

In Processor.cpp your signature should look like int Processor::codeParams(char code) to let the compiler know that is Processor's codeParams and not a random function named codeParams that happens to also take a character.

RyanP
  • 1,898
  • 15
  • 20