使用子类定义类数组

时间:2013-07-28 09:39:46

标签: c++ c visual-studio-2010

无法准确地想出正确的标题,但是当我为我的程序设置const数据时,似乎总会出现这个问题。我的程序基本上是一个轻量级汇编程序,只是我自定义代码编译器的一小部分。

CAssembler.h

struct sOperand
{
    bool used;
    eOperandType type;
    int size;
};

struct sOpcodeDefinition
{
    bool used;
    BYTE opcode;
    BYTE extended_opcode;
    sOperand operands[5];
};

struct sInstructionDefinition
{
    eMnemonicInstruction instruction;
    sOpcodeDefinition opcodes[16];
};

CAssembler.cpp

#define MNEMONIC(a,b) {a,b}
#define OPCODE(a,b,c) {true,OPCODE_##a,b,c}
#define OPERAND(a,b) {true,(eOperandType)OPERAND_##a,b}

sInstructionDefinition OpcodeDefinitionTable[NUM_X86_OPCODES] = {
    MNEMONIC(INC,
        OPCODE(INC_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(INC_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(INC_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(INC_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(INC_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(INC_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(INC_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(INC_DI, 0, OPERAND(REGISTER_DI, 4))
        ),
    MNEMONIC(DEC,
        OPCODE(DEC_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(DEC_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(DEC_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(DEC_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(DEC_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(DEC_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(DEC_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(DEC_DI, 0, OPERAND(REGISTER_DI, 4))
        ),
    MNEMONIC(PUSH,
        OPCODE(PUSH_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(PUSH_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(PUSH_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(PUSH_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(PUSH_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(PUSH_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(PUSH_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(PUSH_DI, 0, OPERAND(REGISTER_DI, 4))
        ),
    MNEMONIC(POP,
        OPCODE(POP_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(POP_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(POP_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(POP_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(POP_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(POP_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(POP_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(POP_DI, 0, OPERAND(REGISTER_DI, 4))
        ),
};

显然我的目标是拥有一个sInstructionDefinition数组并填充它们的对象数组成员等。

不幸的是,编译后的代码中缺少每个sInstructionDefinition的第二个sOpcodeDefinition。我假设sOperand成员也可能会发生同样的事情。有什么想法以及初始化这个大型嵌套结构的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

你的MNEMONIC宏有2个参数,但是你提供了9个。你可能打算写:

   MNEMONIC(INC,
        {
        OPCODE(INC_AX, 0, {OPERAND(REGISTER_AX, 4)}),
        OPCODE(INC_CX, 0, {OPERAND(REGISTER_CX, 4)}),
        // etc..
        }
     ) // etc

请注意,操作码宏中的花括号初始化结构,而上面代码中的额外大括号用于初始化数组。

编辑:请注意,上面的代码仍然不起作用,因为预处理器仍会将逗号视为参数分隔符。

答案 1 :(得分:1)

使用可变参数宏找到了一个很好的解决方案...奇怪的是如何在{}中手动包装OPCODE用法不起作用。但现在,第2,第3,第4等sOpcodeDefinition定义现在已正确编译。

#define MNEMONIC(a,...) {a,{__VA_ARGS__}}
#define OPCODE(a,b,...) {true,OPCODE_##a,b,{__VA_ARGS__}}
#define OPERAND(a,b) {true,(eOperandType)OPERAND_##a,b}
#define NULL_OPERAND {false,BAD_OPERAND,0}

sInstructionDefinition OpcodeDefinitionTable[NUM_MNEMONICS] = {
    MNEMONIC(INC,
        OPCODE(INC_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(INC_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(INC_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(INC_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(INC_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(INC_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(INC_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(INC_DI, 0, OPERAND(REGISTER_DI, 4))
    ),
    MNEMONIC(DEC,
        OPCODE(DEC_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(DEC_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(DEC_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(DEC_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(DEC_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(DEC_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(DEC_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(DEC_DI, 0, OPERAND(REGISTER_DI, 4))
    ),
    MNEMONIC(PUSH,
        OPCODE(PUSH_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(PUSH_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(PUSH_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(PUSH_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(PUSH_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(PUSH_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(PUSH_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(PUSH_DI, 0, OPERAND(REGISTER_DI, 4))
    ),
    MNEMONIC(POP,
        OPCODE(POP_AX, 0, OPERAND(REGISTER_AX, 4)),
        OPCODE(POP_CX, 0, OPERAND(REGISTER_CX, 4)),
        OPCODE(POP_DX, 0, OPERAND(REGISTER_DX, 4)),
        OPCODE(POP_BX, 0, OPERAND(REGISTER_BX, 4)),
        OPCODE(POP_SP, 0, OPERAND(REGISTER_SP, 4)),
        OPCODE(POP_BP, 0, OPERAND(REGISTER_BP, 4)),
        OPCODE(POP_SI, 0, OPERAND(REGISTER_SI, 4)),
        OPCODE(POP_DI, 0, OPERAND(REGISTER_DI, 4))
    ),
};