Sto scrivendo un emulatore di microprocessore in C++ e uno dei miei obiettivi era rendere il codice molto leggibile. Per implementare i codici operativi, ho una struttura che sto usando per rappresentare le singole istruzioni del processore e contiene sia l'opcode che la distanza per far avanzare il contatore del programma. L'idea era di raggruppare le informazioni relative a ciascuna istruzione.C++: struct member in a switch statement
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};
mio piano originale era quello di definire tutti i codici operativi che utilizzano questa struct, come ho avuto l'impressione che const
è preferito utilizzare #define
per le costanti C++. Inoltre, sarei in grado di raggruppare in modo pulito tutti gli attributi correlati di un opcode.
Tuttavia, sembra che questo non funzioni per le istruzioni switch, come inizialmente previsto. Il seguente codice non verrà compilato e Visual Studio restituisce l'errore "espressione del caso non costante".
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;
}
ho scaricato anche la più recente di Visual Studio compilatore (MSVC novembre 2013 CTP) per cercare di sfruttare constexpr
da C++ 11, ma ho avuto lo stesso problema, e non si compila. Qui ho convertito la mia struttura in una classe e ho tentato di sfruttare constexpr
, per garantire che i membri di un instruction
potessero essere usati come costanti in fase di compilazione.
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);
Io non sono davvero sicuro di cosa fare a questo punto, dal momento che sembra che il compilatore non capisce che i valori struct vengono assegnati come costanti.
Quindi esiste un modo per utilizzare un membro struct in un'istruzione switch o devo semplicemente passare a utilizzare #define
? In alternativa, c'è un modo migliore per farlo mantenendo ancora un'organizzazione? Gradirei davvero qualsiasi aiuto o intuizione che tu possa offrire, grazie!
EDIT: dispiace, avrei fatto più chiaro che next_instruction è solo un int, non un instruction
struct/oggetto
La tua versione 'constexpr' dovrebbe funzionare. Quindi potrebbe essere che il tuo compilatore non lo implementa correttamente. Ma dovresti comunque mostrare la definizione di next_instruction. – juanchopanza
'constexpr' è implementato solo in Visual Studio Next (14), Visual Studio 2013 non lo implementa. Inoltre, la versione più recente di VS è l'aggiornamento 3 del 2013, non il CTP di novembre. – Drop
Inoltre, il tuo codice profuma di "Type Switch antipattern". Probabilmente potresti usare il polimorfismo qui (dinamico o statico) invece dei condizionali: [Metodi per eliminare lo switch in codice] (http://stackoverflow.com/questions/126409/ways-to-eliminate-switch-in-code). La maggior parte delle volte potrebbe essere ancora più veloce (dovrai profilare il profilo). – Drop