我的C++使用Clang编译,但不使用GCC

My C++ compiles in Clang but not GCC

本文关键字:GCC C++ 使用 Clang 编译 我的      更新时间:2023-10-16

我正在用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;
}

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

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

事实上,我甚至对它使用clang构建感到惊讶,因为它不应该,也不适合我编译

这可能与内部隐式include清理有关,因为过去有一些gcc变体,其中一些include是隐式的,而对于开发人员来说,它们实际上是显式地依赖于某些东西。这不是一个好的做法。始终明确包含您使用的内容。

你必须在顶部修改这个:

#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