Piszę emulator mikroprocesora w C++, a jednym z moich celów było uczynienie go bardzo czytelnym. Aby zaimplementować opkodami, mam strukturę, której używam do reprezentowania poszczególnych instrukcji procesora, i zawiera zarówno kod operacji, jak i odległość do przekroczenia licznika programu. Pomysł polegał na grupowaniu powiązanych informacji o każdej instrukcji.C++: członek struktury w oświadczeniu przełącznika
struct instruction
{
const int opcode; // instruction opcode
const int op_size; // how far to advance Program Counter
};
const instruction HALT{0x76, 1};
const instruction NOP {0x00, 1};
Mój pierwotny plan był, aby zdefiniować wszystkie opcodes pomocą tej struktury, jak byłem pod wrażeniem, że const
było preferowane do korzystania #define
dla stałych C++. Ponadto byłbym w stanie uporządkować wszystkie powiązane atrybuty opcode.
Wydaje się jednak, że to nie zadziała w przypadku instrukcji switch, jak pierwotnie zamierzałem. Poniższy kod nie zostanie skompilowany, a Visual Studio podaje błąd "case expression not constant".
switch (next_instruction) { // next_instruction is an int parsed from a file
case HALT.opcode:
// do stuff
break;
case NOP.opcode:
// do stuff
break;
default:
std::cout << "Unrecognized opcode" << std::endl;
break;
}
Ja również pobrać najnowszą kompilator języka Visual Studio (MSVC listopada 2013 CTP), aby spróbować dźwigni constexpr
od C++ 11, ale miałem ten sam problem, i nie będzie skompilować. Tutaj skonwertowałem swoją strukturę do klasy i próbowałem wykorzystać constexpr
, aby zapewnić, że członkowie instruction
mogą być używane jako stałe w czasie kompilacji.
class Instruction
{
public:
constexpr Instruction(int code, int size) : opcode(code), op_size(size) {}
const int opcode; // instruction opcode
const int op_size; // how far to advance Program Counter
};
constexpr Instruction HALT(0x76, 1);
constexpr Instruction NOP (0x00, 1);
Nie jestem pewien, co zrobić w tym momencie, ponieważ wydaje się, że kompilator nie rozumie, że wartości struct są przypisane jako stałe.
Czy istnieje jakiś sposób użycia elementu struct w instrukcji switch, czy powinienem po prostu przełączyć się na używanie #define
? Alternatywnie, czy istnieje lepszy sposób, aby to zrobić, zachowując jednocześnie pewną organizację? Naprawdę doceniam każdą pomoc lub wgląd, jaki możesz zaoferować, dziękuję!
EDIT: Przepraszam, powinny były to jasne, że next_instruction jest tylko int, a nie instruction
struct/przedmiot
Twoja wersja 'constexpr' powinna działać. Możliwe, że Twój kompilator nie implementuje tego poprawnie. Ale i tak powinieneś pokazać definicję "next_instruction". – juanchopanza
'constexpr' jest implementowany tylko w Visual Studio Next (14), Visual Studio 2013 go nie implementuje. Ostatnia wersja VS to 2013 aktualizacja 3, a nie listopadowe CTP. – Drop
Twój kod również pachnie "Antypatternem typu przełącznika". Prawdopodobnie możesz użyć polimorfizmu tutaj (dynamiczny lub statyczny) zamiast warunków warunkowych: [Sposoby na wyeliminowanie zmiany w kodzie] (http://stackoverflow.com/questions/126409/ways-to-eliminate-switch-incode). Najczęściej może być jeszcze szybszy (musisz go profilować). – Drop