-1

I'm making a small virtual machine; in my virtual machine I read instructions from a binary file. Each instruction is 1 byte in size. When the VM starts, it loads the binary file into a vector. Then I use a switch and a for loop to execute the instructions.

But here's where my question starts. I have a vector called "Stack"; it's my virtual machines stack for the program that's running. The problem is I want to store different kinds of data in the vector (Signed and Unsigned Integers, Strings, etc ...).

To do this I created my own object (robj) and made the vector of type "robj". This lets me store the kind of data I want, but my question is: is this wasteful?

Here's the implementation of my object:

class robj {

public:
    int signed_int = 0;
    unsigned int unsigned_int = 0;

};

As you can see, my object is really small at the moment, but it will get larger as I add things like strings. The part that I think is wasteful is that, if I store a signed integer on the stack I also have to store an unsigned one because the object defines both types of integers. And this problem will only get worse as I make the object bigger.

So I'd just like to know, is there a less wasteful way to do this?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Francis
  • 33
  • 3
  • 5
    If I understand your question correctly, a [union](http://en.cppreference.com/w/cpp/language/union) may solve your problem. – Frédéric Hamidi Dec 08 '14 at 11:29
  • You might find [this discussion](http://www.cs.rit.edu/~afb/20013/plc/guile/guile_17.html) about hacks you'd never want to think of enlightening. – 5gon12eder Dec 08 '14 at 11:34

2 Answers2

4

This is what Boost.Variant is for. It implements discriminated unions so you don't have to:

std::vector<boost::variant<
   int,
   unsigned int
>> v;
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
1

There can be 2 solutions

  1. Use union
union robj {
  int signed_int;
  unsigned int unsigned int;
};
  1. Use inheritance
class type_base
{
  type_data my_type;
public:
  type_base(const type_data &t) : my_type(t) {}
  virtual parse_data() = 0;
  virtual serialize_data() = 0;
  virtual type_data get_type() {
    return my_type;
  }
  virtual type_base *clone() = 0;
};

class signed_int : public type_base {
public:
  int signed_int;
};

You can also templatize your type where the template inherits from type_base.

Make sure that you never make a vector of type_base which can cause object slicing. Thanks to Alain for his comment

Mohit Jain
  • 30,259
  • 8
  • 73
  • 100
  • 4
    You can't have a `vector` and insert `signed_int`, because of the slicing problem. – alain Dec 08 '14 at 11:45
  • In C++ it is only permitted to access the last-set member of a union. I would just store an int and convert to unsigned int when required, or vice versa. – M.M Dec 08 '14 at 12:00
  • @alain vector can contain raw bytes which can be parsed by checking the instruction using `parse_data()` or can be dumped into stack similarly. Or you can have indirect addressing mode and can store `shared_ptr` in stack. – Mohit Jain Dec 08 '14 at 12:03
  • Yes, but as your answer stands now, I find it a bit misleading. – alain Dec 08 '14 at 12:12
  • @alain May be the answer is not well enough written. Using a tagged union etc would end up wasting space, that's why I took second approach years ago to implment a postscript interpreter which has many types and is stack based. Based on my experience, this data structure worked well for me. – Mohit Jain Dec 08 '14 at 12:17
  • Recommended reading: http://stackoverflow.com/questions/274626/what-is-object-slicing – alain Dec 08 '14 at 12:52
  • @alain FYI I understand what object slicing is after programming in `C++` for 8 years. If you believe my answer is not well written go ahead and edit it and make it better for the readers. If you think it is wrong, downvote it. If you think something is missing, or not clear, discuss it. I suggested using raw data or stack of shared pointers (indirect addressing) both of which don't suffer object slicing. – Mohit Jain Dec 08 '14 at 13:35
  • Sorry, I really didn't want to offend you. My comments are meant for those that don't know about object slicing yet. I fear somebody might create a `vector` because you didn't include a warning about it in your answer. – alain Dec 08 '14 at 15:02
  • @alain sorry for overreacting. I really wanted you to make the answer better. I will edit my answer from your inputs. – Mohit Jain Dec 08 '14 at 17:12
  • My edits have to be approved by others, I'm < 2k. And adding to an answer is not likely to be approved, I guess. Now it's a good answer IMO, +1. – alain Dec 08 '14 at 18:57
  • @alain Thanks. Now I understood. Please keep contributing to help others and share knowledge. – Mohit Jain Dec 09 '14 at 02:30