Question

I'm writing a virtual machine in C++ and it compiles in Clang but it just gives loads of errors when I compile it in GCC. Can anyone tell me why? I don't see how my code will compile in one compiler but it won't compile in another compiler. Should they now be the same?

Here's the code:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

#define OP_EOI 0
#define OP_EOP 1
#define OP_PUSH 2
#define OP_POP 3
#define OP_PRINT 4
#define OP_ADD 5
#define OP_MUL 6
#define OP_SUB 7

using namespace std;

class reedoovm {

    private:
        string filedata;
        string instruction;
        string file;
        int instr;
        int instructionCount;
        int instructionPointer;
        int stack;

    public:
        string load_program(string filename) {
            ifstream rdfile(filename);
            while(rdfile >> instruction) {          /* Get each instruction */
                    filedata += instruction;        /* Append the instruction to filedata */
                    filedata += ",";                /* Append a comma to separate each instruction */
                    instructionCount++;
                }
            rdfile.close();                         /* Close the file */
            return filedata;                        /* Return the filedata */
        }

        int *instrToArr(string file) {
            stringstream hextoint;
            unsigned int value;
            string s = file;                        /* store fconv in a variable "s" */
            string delimiter = ",";                 /* The delimiter */
            size_t pos = 0;
            string token;
            int i = 0;
            int inst;
            static int* instarray;
            instarray = (int*) calloc(instructionCount,sizeof(int));
            while ((pos = s.find(delimiter)) != string::npos) {     /* Convert hex instructions to decimal */
                token = s.substr(0, pos);
                stringstream hextoint(token);
                hextoint >> hex >> value;
                if (i < instructionCount) {
                    instarray[i] = value;
                    i++;
                }
                s.erase(0, pos + delimiter.length());
            }
            return instarray;
        }

        int * instructionArray(int instructionArray[]) {
            return instructionArray;
        }

        int getNextIntruction(int instructions[], int i) {
            return instructions[i];
        }

        void do_PRINT() {

        }

        void do_PUSH(int instructions, int i) {
            //cout << instructions[i + 1] << endl;
        }

        void run_program(int instructions[], string file) {
            int loop = 1;
            int i = 0;
            string delimiter = ",";                 /* The delimiter */
            size_t pos = 0;
            string token;
            int iterator = 0;
            instructionCount = count(file.begin(), file.end(), ',');
            int instructionOrLiteralArray[instructionCount];
            while ((pos = file.find(delimiter)) != string::npos) {     /* Convert hex instructions to decimal */
                token = file.substr(0, pos);
                if (token.length() == 2) {                             /* Operation */
                    instructionOrLiteralArray[iterator] = 0;
                } else {
                    instructionOrLiteralArray[iterator] = 1;           /* Literal */
                }
                iterator++;
                 file.erase(0, pos + delimiter.length());
            }
            while (loop) {

                instr = getNextIntruction(instructions, i);

                if (instr == OP_EOI && instructionOrLiteralArray[i] == 0) {
                    cout << "EOI" << endl;
                } else if (instr == OP_EOI && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (instr == OP_PUSH && instructionOrLiteralArray[i] == 0) {
                    do_PUSH(instr, i);
                } else if (instr == OP_PUSH && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (instr == OP_PRINT && instructionOrLiteralArray[i] == 0) {
                    do_PRINT();
                } else if (instr == OP_PRINT && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (instr == OP_POP && instructionOrLiteralArray[i] == 0) {
                    cout << "POP" << endl;
                } else if (instr == OP_POP && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (instr == OP_ADD && instructionOrLiteralArray[i] == 0) {
                    cout << "ADD" << endl;
                } else if (instr == OP_ADD && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (instr == OP_SUB && instructionOrLiteralArray[i] == 0) {
                    cout << "MUL" << endl;
                } else if (instr == OP_MUL && instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                else if (instructionOrLiteralArray[i] == 1) {
                    cout << "Literal" << endl;
                }

                if (i < instructionCount) {
                    i++;
                } else {
                    loop = 0;
                }
            }
        }

        void execute_program(string s) {
            file = load_program(s);
            int * arr = instrToArr(file);
            int * instructions = instructionArray(arr);
            run_program(instructions, file);
        }       

};

int main(int argc, char* argv[]) {
    reedoovm rd;
    rd.execute_program(argv[1]);
    return 0;
}
Was it helpful?

Solution

You are not include algorithm for std::count.

instructionCount = count(file.begin(), file.end(), ',');

I am actually even surprised that it builds with clang because it should not, and it does not compile for me.

It might have something to do with internal implicit include clean up as there used to be gcc variants where some includes were implicit and it was hidden for the developer that they are actually explicitly depending on something. This is not a good practice. Always include explicitly what you use.

You have to amend this at the top:

#include <algorithm>

Also, note that when you write this line:

ifstream rdfile(filename);

It means you will need to use the -std=c++11 option for the compiler, let it be gcc or clang because that constructor type for ifstream that accepts std::string was only introduced in C++11.

For any previous version, you would need to change filename to filename.c_str() to get the char* name of the file.

Therefore, this is how I made your code compiling after adding the extra explicit include:

g++ -std=c++11 main.cpp

and

clang -std=c++11 main.cpp
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top