我有一些包含此typedef的遗留代码:
typedef enum simple_op_enum {
#define SOP(OPCODE, NAME, FORM, SUIFOP) OPCODE ,
#include "simple_ops.def"
LAST_OP
} simple_op;
#include文件包含以下几行格式:
/* no operand instructions */
SOP( NOP_OP, "nop ", BASE_FORM, io_nop)
令牌“simple_op”稍后出现在结构中:
typedef struct simple_instr_struct {
simple_op opcode; /* the opcode */
有几件我不明白的事情:
在#define语句的末尾加上逗号可以实现什么?我认为这是非法的。
enum正在完成的工作,特别是LAST_OP
如何在simple_instr_struct中访问操作码的值?
答案 0 :(得分:1)
这不是非法的,它是预处理器替换所有SOP(x, y, z)
实例的一部分。
它正在使用simple_ops.def
中的内容创建枚举。由于该文件的内容为SOP(w, x, y, z)
,因此它们将全部变为w
,enum
将变为:
typedef enum simple_op_enum {
NOP_OP , // <- notice the space before the comma, like the #define does
... // the others
LAST_OP
} simple_op;
它还使LAST_OP
成为最后一个枚举值。这可能是代码可以使用LAST_OP
来确定有多少枚举值(或最高枚举值,或类似的值)。
这个#include
是一个聪明的技巧,所以定义可以在同一个地方(文件)和#include
它只是定义SOP
的代码是什么它需要它。然后修改一个文件将影响需要它的整个代码,代码以任何需要的方式使用它们。例如,某些代码可能只需要名称,因此它会将SOP
定义为#define SOP(w, x, y, z) x
以提取名称。
3)您可以通过执行simple_instr_struct_instance.opcode
答案 1 :(得分:1)
如果对宏有疑问,您可以随时使用预处理器来查看它们的扩展方式:
gcc -E file.c -o file.txt
如果包含许多头文件,输出会很大,但你会在那里找到你的宏 - 可能是在最后
答案 2 :(得分:0)
它会将操作码作为枚举
提取出来枚举需要逗号分隔,因此它采用OPCODE并放置一个,之后有效生成
typedef enum simple_op_enum {
NOP_OP, BLAH , WHATEVER , ANOTHER ,
LAST_OP
} simple_op;
枚举的要点是拥有所有可用操作码的枚举。
LAST_OP对于了解你最终会使用多少个操作码很有用,也意味着枚举列表中最后一个没有悬空的逗号。
如果您有结构的实例'blah',那么您可以通过blah.opcode = NOP_OP;
答案 3 :(得分:0)
#define结束时的逗号是合法的。它是宏的一部分。枚举的常量用逗号分隔,这个宏担心这个。
枚举只是一个var,它可以包含您在枚举声明中指定的任何值。因为它们被翻译成数字,所以LAST_OP将等于可能性的数量。
您可以访问以下成员:
struct simple_instr_struct a;
a.opcode=LAST_OP;
答案 4 :(得分:0)
逗号只是使用宏时将发生的文本替换的一部分。在这种情况下,在每个操作码之后添加一个逗号,以便列表生成有效的enum
语法。
#define
和#include
的结果是枚举,如下所示:
typedef enum simple_op_enum {
NOP_OP,
.
.
.
LAST_OP
} simple_op;
通过查看通过C预处理器运行源代码的输出,您可以看到相同的内容。 LAST_OP
只是新枚举中的最后一个条目。
您需要定义该类型的变量:
struct simple_instr_struct myStruct;
然后访问您关注的字段:
myStruct.opcode