Unknow error

I have this code below implement a simple Virtual Machine to load instruction and do things to data. The problem is the exception I throw when meet a " " at the begin of the instruction, or at the end. Or "," in somewhere else in a string Instruction not the one between two registers. Please have a look at my work and help me figure out this problem, I really need your guys' help.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#define _CRT_SECURE_NO_WARNINGS

#include <string>
#include <iostream>
#include <cstring>
using namespace std;
 enum DataType { NONE, INT };

struct GReg {
    int data;
    DataType type;
};

struct Instruction {
    string code;
    string op1;
    string op2;
};

class VM {
private:
    int IP; // IP register
    GReg reg[7]; // General register: R1 -> R7
    Instruction codeMemory[20];
    int codeLoadedIndex;
    
public:
    VM() { 
        this->IP = 0;
        for (int i = 0; i < 7; i++) {
            reg[i].type = NONE;
        }
        this->codeLoadedIndex = 0;
    }
    
    // Your student code here
    void move(string dest, string src) {
        int idxd = stoi(dest.substr(1))-1;
        if (src[0] == 'R')
        {
            int idxs = stoi(src.substr(1))-1;
            reg[idxd].data=reg[idxs].data;
            reg[idxd].type=reg[idxs].type;
        }
        else 
        {
            int tmp = stoi(src);
            reg[idxd].data=tmp;
            reg[idxd].type=INT;
        }
        IP++;
    }
    
    void output(string dest) {
    int idx = stoi(dest.substr(1))-1;
        cout<< reg[idx].data;
        IP++;
    
    }

    void load(string instruction) {
    Instruction ins;
    char* cstr = new char[instruction.length()+1];
    strcpy(cstr,instruction.c_str());
    char cma[]=" ,";
    char* token=strtok(cstr,cma);
    ins.code=string(token);
    int i=0;
        while (token)
        {
           
            //cout<<token<<endl;
            token=strtok(NULL,cma); 
            
            if (i == 0)
            ins.op1=string(token);
            else if (i==1)
            ins.op2=string(token);
            else throw "Invalid Instruction";
            i++;
            cout<<ins.op1<<" "<<ins.op2;
            
        }
    }

    void exec() {
        for (int i=0;i<codeLoadedIndex; i++){
		Instruction ins=codeMemory[i];
		if (ins.code == "Move") this->move(ins.op1, ins.op2);
		else if (ins.code == "Output") this->output(ins.op1);

	}
    }
    // End: Your student code here
    
    void dump() {
        cout << endl << "VM Info: " << endl;
        cout << "IP: " << this->IP << endl;
        for (int i = 0; i < 7; i++) {
            
            if (reg[i].type != NONE) {
                cout << "R" << i + 1 << ": " << reg[i].data << endl;
            }
        }
    }
};
int main()
{

}
Last edited on
When asking a question, please post code that will compile, or at least sort of compile. In your case, you left out all the include files, resulting in the output below from my compiler. I'm not willing to slog through that mess.

foo.cxx:9:5: error: ‘string’ does not name a type; did you mean ‘struct’?
     string code;
     ^~~~~~
     struct
foo.cxx:10:5: error: ‘string’ does not name a type; did you mean ‘struct’?
     string op1;
     ^~~~~~
     struct
foo.cxx:11:5: error: ‘string’ does not name a type; did you mean ‘struct’?
     string op2;
     ^~~~~~
     struct
foo.cxx:31:15: error: ‘string’ has not been declared
     void move(string dest, string src) {
               ^~~~~~
foo.cxx:31:28: error: ‘string’ has not been declared
     void move(string dest, string src) {
                            ^~~~~~
foo.cxx:48:17: error: ‘string’ has not been declared
     void output(string dest) {
                 ^~~~~~
foo.cxx:55:15: error: ‘string’ has not been declared
     void load(string instruction) {
               ^~~~~~
foo.cxx:88:5: error: expected ‘}’ at end of input
     }
     ^
foo.cxx: In member function ‘void VM::move(int, int)’:
foo.cxx:32:30: error: request for member ‘substr’ in ‘dest’, which is of non-class type ‘int’
         int idxd = stoi(dest.substr(1))-1;
                              ^~~~~~
foo.cxx:32:20: error: ‘stoi’ was not declared in this scope
         int idxd = stoi(dest.substr(1))-1;
                    ^~~~
foo.cxx:33:18: error: invalid types ‘int[int]’ for array subscript
         if (src[0] == 'R')
                  ^
foo.cxx:35:33: error: request for member ‘substr’ in ‘src’, which is of non-class type ‘int’
             int idxs = stoi(src.substr(1))-1;
                                 ^~~~~~
foo.cxx: In member function ‘void VM::output(int)’:
foo.cxx:49:25: error: request for member ‘substr’ in ‘dest’, which is of non-class type ‘int’
     int idx = stoi(dest.substr(1))-1;
                         ^~~~~~
foo.cxx:49:15: error: ‘stoi’ was not declared in this scope
     int idx = stoi(dest.substr(1))-1;
               ^~~~
foo.cxx:50:9: error: ‘cout’ was not declared in this scope
         cout<< reg[idx].data;
         ^~~~
foo.cxx: In member function ‘void VM::load(int)’:
foo.cxx:57:39: error: request for member ‘length’ in ‘instruction’, which is of non-class type ‘int’
     char* cstr = new char[instruction.length()+1];
                                       ^~~~~~
foo.cxx:58:29: error: request for member ‘c_str’ in ‘instruction’, which is of non-class type ‘int’
     strcpy(cstr,instruction.c_str());
                             ^~~~~
foo.cxx:58:5: error: ‘strcpy’ was not declared in this scope
     strcpy(cstr,instruction.c_str());
     ^~~~~~
foo.cxx:58:5: note: suggested alternative: ‘struct’
     strcpy(cstr,instruction.c_str());
     ^~~~~~
     struct
foo.cxx:60:17: error: ‘strtok’ was not declared in this scope
     char* token=strtok(cstr,cma);
                 ^~~~~~
foo.cxx:60:17: note: suggested alternative: ‘static’
     char* token=strtok(cstr,cma);
                 ^~~~~~
                 static
foo.cxx:61:9: error: ‘struct Instruction’ has no member named ‘code’
     ins.code=string(token);
         ^~~~
foo.cxx:61:14: error: ‘string’ was not declared in this scope
     ins.code=string(token);
              ^~~~~~
foo.cxx:61:14: note: suggested alternative: ‘struct’
     ins.code=string(token);
              ^~~~~~
              struct
foo.cxx:67:26: error: ‘NULL’ was not declared in this scope
             token=strtok(NULL,cma);
                          ^~~~
foo.cxx:70:17: error: ‘struct Instruction’ has no member named ‘op1’
             ins.op1=string(token);
                 ^~~
foo.cxx:72:17: error: ‘struct Instruction’ has no member named ‘op2’
             ins.op2=string(token);
                 ^~~
foo.cxx:74:24: error: ‘out_of_range’ is not a member of ‘std’
             throw std::out_of_range("Invalid Instruction");//the VS compiler said the error came from here
                        ^~~~~~~~~~~~
foo.cxx: In member function ‘void VM::exec()’:
foo.cxx:84:11: error: ‘struct Instruction’ has no member named ‘code’
   if (ins.code == "Move") this->move(ins.op1, ins.op2);
           ^~~~
foo.cxx:84:42: error: ‘struct Instruction’ has no member named ‘op1’
   if (ins.code == "Move") this->move(ins.op1, ins.op2);
                                          ^~~
foo.cxx:84:51: error: ‘struct Instruction’ has no member named ‘op2’
   if (ins.code == "Move") this->move(ins.op1, ins.op2);
                                                   ^~~
foo.cxx:85:16: error: ‘struct Instruction’ has no member named ‘code’
   else if (ins.code == "Output") this->output(ins.op1);
                ^~~~
foo.cxx:85:51: error: ‘struct Instruction’ has no member named ‘op1’
   else if (ins.code == "Output") this->output(ins.op1);
                                                   ^~~
foo.cxx: At global scope:
foo.cxx:88:5: error: expected unqualified-id at end of input
     }
Okay, I added:
1
2
3
4
#include <string>
#include <iostream>
#include <cstring>
using namespace std;
to the beginning, and
}
to the end and it compiles for me.
The problem is the exception I throw
//the VS compiler said the error came from here

Is this a compiler error, or a runtime error?
If runtime: You're throwing an exception. We can't see where you are calling the load function, so we have no idea how you are handling this exception. Do you ever catch this exception?

If compile-time, perhaps it's flagging the fact that you have dead code or something, and your default settings make this an error instead of a warning.
- First, line 75 is dead code.
- Therefore, i is never incremented to 1 or beyond.
- Therefore, lines 71 to 76 are all dead code.
I am assuming that is not intentional, but you never told us what the actual error is.
With VS2019, this compiles OK at level 4 warnings with no errors/warnings:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define _CRT_SECURE_NO_WARNINGS

#include <string>
#include <iostream>
#include <cstring>
using namespace std;

enum DataType { NONE, INT };

struct GReg {
	int data;
	DataType type;
};

struct Instruction {
	string code;
	string op1;
	string op2;
};

class VM {
private:
	int IP; // IP register
	GReg reg[7]; // General register: R1 -> R7
	Instruction codeMemory[20];
	int codeLoadedIndex;

public:
	VM() {
		this->IP = 0;
		for (int i = 0; i < 7; i++) {
			reg[i].type = NONE;
		}
		this->codeLoadedIndex = 0;
	}

	// Your student code here
	void move(string dest, string src) {
		int idxd = stoi(dest.substr(1)) - 1;
		if (src[0] == 'R')
		{
			int idxs = stoi(src.substr(1)) - 1;
			reg[idxd].data = reg[idxs].data;
			reg[idxd].type = reg[idxs].type;
		} else
		{
			int tmp = stoi(src);
			reg[idxd].data = tmp;
			reg[idxd].type = INT;
		}
		IP++;
	}

	void output(string dest) {
		int idx = stoi(dest.substr(1)) - 1;
		cout << reg[idx].data;
		IP++;

	}

	void load(string instruction) {
		Instruction ins;
		char* cstr = new char[instruction.length() + 1];
		strcpy(cstr, instruction.c_str());
		char cma[] = " ,";
		char* token = strtok(cstr, cma);
		ins.code = string(token);
		int i = 0;
		while (token)
		{

			//cout<<token<<endl;
			token = strtok(NULL, cma);

			if (i == 0)
				ins.op1 = string(token);
			else if (i == 1)
				ins.op2 = string(token);
			else {
				throw std::out_of_range("Invalid Instruction");//the VS compiler said the error came from here
				i++;
			}

		}
	}

	void exec() {
		for (int i = 0; i < codeLoadedIndex; i++) {
			Instruction ins = codeMemory[i];
			if (ins.code == "Move") this->move(ins.op1, ins.op2);
			else if (ins.code == "Output") this->output(ins.op1);

		}
	}
};

int main()
{

}

Hmm yeah, g++ doesn't warn that there is unreachable code, as well. Maybe it doesn't bother warning on dead code within if-statements. Looks like the warning capabilities here are very limited. Sounds like OP's issue is the runtime issue, then.
As my teacher said, any warning will be treat as error for his testcase, does this means that my code is wrong
The code produced no warnings at L4 compile with VS2019. This does not mean that your code is not wrong. It could well have logic and other run-time issues. You'll need to test it and debug it as needed in order to ensure it works as required/expected.

Here the input and output of this exercise:
1
2
3
4
5
6
VM* vm = new VM();
vm->load("Move R1, 7");
vm->load("Output R1");
vm->exec();
vm->dump();
delete vm;

1
2
3
4
7
VM Info:
IP: 2
R1: 7


I had just edit my code but it always throw this error (the teacher compiler, not mine)
1
2
3
***Error***
terminate called after throwing an instance of 'char const*'
Aborted (core dumped)
There is a place in your code where you most likely are doing:
throw "some string literal";

You should catch this exception via:
1
2
3
4
5
6
7
8
try
{
    // existing code here
}
catch (const char* msg)
{
    std::cout << "Exception caught: " << msg << '\n';
}

Or, the issue is that you should avoid the logic that causes the exception in the first place.
Last edited on
Topic archived. No new replies allowed.