我的C ++编译在Clang但不是GCC

时间:2014-04-27 09:25:37

标签: c++ gcc clang vm-implementation

我正在用C ++编写一个虚拟机,它在Clang中编译,但是当我在GCC中编译它时,它只会产生大量错误。谁能告诉我为什么?我不知道我的代码将如何在一个编译器中编译,但它不会在另一个编译器中编译。它们现在应该是一样的吗?

以下是代码:

#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;
}

1 个答案:

答案 0 :(得分:3)

您不包括std :: count的算法。

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

我实际上甚至对使用clang构建它感到惊讶,因为它不应该,并且它不会为我编译。

它可能与内部隐式包含清理有关,因为曾经存在gcc变体,其中一些包含是隐式的,并且开发人员隐藏它们实际上明确取决于某些内容。这不是一个好习惯。始终明确包含您使用的内容。

你必须在顶部修改:

#include <algorithm>

另外,请注意写下这一行时:

ifstream rdfile(filename);

这意味着你需要为编译器使用-std=c++11选项,让它为gcc或clang,因为接受std :: string的ifstream的构造函数类型仅在C ++ 11中引入。

对于任何以前的版本,您需要将filename更改为filename.c_str()以获取文件的char *名称。

因此,这是我在添加额外显式include:

后编译代码的方法
g++ -std=c++11 main.cpp

clang -std=c++11 main.cpp