Я пишу микропроцессорный эмулятор на C++, и одной из моих целей было сделать его очень читаемым. Чтобы реализовать коды операций, у меня есть структура, которую я использую для представления отдельных инструкций процессора, и она содержит как код операции, так и способ продвижения счетчика программ. Идея состояла в том, чтобы группировать соответствующую информацию о каждой инструкции.C++: член структуры в операторе switch
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};
Мой первоначальный план был определить все опкоды, используя эту структуру, так как я был под впечатлением, что const
предпочтение было отдано с использованием #define
для констант C++. Кроме того, я смог бы сгруппировать все связанные атрибуты кода операции.
Однако, похоже, что это не будет работать для операторов switch, как я и предполагал. Следующий код не будет компилироваться, а Visual Studio дает ошибку «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;
}
Я также скачал последнюю Visual Studio компилятор (MSVC ноября 2013 CTP), чтобы попытаться левериджа constexpr
от C++ 11, но у меня была такая же проблема, и она не будет компилироваться. Здесь я преобразовал свою структуру в класс и попытался использовать constexpr
, чтобы гарантировать, что члены instruction
могут использоваться как константы времени компиляции.
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);
Я не совсем уверен, что делать в этой точке, так как кажется, что компилятор не понимает, что значения Struct назначены как константы.
Так можно ли использовать элемент struct в инструкции switch, или я должен просто переключиться на использование #define
? Альтернативно, есть ли лучший способ сделать это, сохраняя при этом некоторую организацию? Я бы очень признателен за любую помощь или прозрение, которое вы можете предложить, спасибо!
EDIT: К сожалению, я должен был бы сделать его более ясным, что next_instruction это просто INT, а не instruction
структура/объект
Ваша версия 'constexpr' должна работать. Поэтому может быть, что ваш компилятор не реализует это правильно. Но вы должны показать определение 'next_instruction' в любом случае. – juanchopanza
'constexpr' реализован только в Visual Studio Next (14), Visual Studio 2013 не реализует его. Кроме того, последняя версия версии VS - обновленная версия 2013 года 3, а не ноябрьская CTP. – Drop
Кроме того, ваш код пахнет «Type Switch antipattern». Вероятно, вы можете использовать здесь полиморфизм (динамический или статический) вместо условных: [Способы устранения коммутатора в коде] (http://stackoverflow.com/questions/126409/ways-to-eliminate-switch-in-code). В большинстве случаев это может быть еще быстрее (вам нужно будет профилировать его). – Drop