提问人:ro88 提问时间:3/2/2023 最后编辑:ro88 更新时间:3/3/2023 访问量:82
在 X 宏 C 中定义相同的元素
defining same elements in X macro C
问:
我一直在探索 X 宏,并创建了这张表
#define FAULT_TABLE(FAULT) \
FAULT(INVALID, FAULT_CATEGORY_NONE, action_none) \
FAULT(COMMS_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(QUEUE_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(SENSOR_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(FAILED_OP FAULT_CATEGORY_1, action_1)
我只是想知道我是否可以具有相同的值并从中生成一个枚举。我的意思是表中第二列的枚举。
以及如何为上面的故障代码分配相同的函数调用
更新只是为了增加更清晰和上下文:当报告这些错误中的任何一个时,我的错误处理程序将查看要执行的类别和函数。有些故障具有相同的动作,属于同一类别。所以我试图弄清楚这是否可以通过 X 宏 .
所以我只想将枚举扩展为
typedef enum {
FAULT_CATEGORY_NONE,
FAULT_CATEGORY_1,
FAULT_CATEGORY_N,
}
此外,我会将表中定义的函数扩展为跳转表。
答:
我只是想知道我是否可以具有相同的值并从中生成一个枚举。我的意思是表中第二列的枚举。
不能复制枚举常量,但可以为不同的枚举常量赋予相同的值。因此,例如,您可以这样做:
#define FAULT_CATEGORY_NONE 0
#define FAULT_CATEGORY_1 1
#define FAULT_TABLE(FAULT) \
FAULT(INVALID, FAULT_CATEGORY_NONE) \
FAULT(COMMS_FAILURE, FAULT_CATEGORY_1) \
FAULT(QUEUE_FAILURE, FAULT_CATEGORY_1) \
FAULT(SENSOR_FAILURE, FAULT_CATEGORY_1) \
FAULT(FAILED_OP, FAULT_CATEGORY_1)
#define FAULT(x, y) x ## _CAT = (y),
enum category {
FAULT_TABLE(FAULT)
DUMMY_CAT
};
这扩展到
enum category {
INVALID_CAT = (0), COMMS_FAILURE_CAT = (1), QUEUE_FAILURE_CAT = (1),
SENSOR_FAILURE_CAT = (1), FAILED_OP_CAT = (1), DUMMY_CAT
};
(为清楚起见,添加了额外的空格)。
但我看不出 X 宏实际上是如何帮助你的。特别是,您对有关分配函数的子问题提出了不同的定义,这是可疑的。FAULT_TABLE
当您可以将同一列表(此处)重用于 () 的多个定义时,X 宏方法提供了一些牵引力。但是,您的示例似乎不太适合此,因为每种用途似乎都需要列表提供不同的数据。我想你可以通过依赖接受一个额外的参数来将它们全部塞进同一个列表中,但你最好只创建常规表。例如:FAULT_TABLE
X
FAULT
FAULT
enum fault {
INVALID, COMMS_FAILURE, QUEUE_FAILURE, SENSOR_FAILURE, FAILED_OP
};
const int fault_category[] = {
[INVALID] = FAULT_CATEGORY_NONE,
[COMMS_FAILURE] = FAULT_CATEGORY_1,
[QUEUE_FAILURE] = FAULT_CATEGORY_1,
[SENSOR_FAILURE] = FAULT_CATEGORY_1,
[FAILED_OP] = FAULT_CATEGORY_1
};
const void (*fault_action[])(void) = {
[INVALID] = action_none,
[COMMS_FAILURE] = action_1,
[QUEUE_FAILURE] = action_1,
[SENSOR_FAILURE] = action_1,
[FAILED_OP] = action_2
};
你当然可以使用 X 宏来生成这样的代码,但我认为你不会节省太多空间,而且我认为结果会不太清楚。
关于问题更新
您似乎希望使用 X 宏方法仅在某个给定的传递列表中为宏的某个参数的每个不同值选择和生成输出。我不敢说这是不可能的,因为聪明的人已经从预处理器中挤出了一些相当令人惊讶的行为,但我有信心说,没有直接的方法可以让预处理器做到这一点。X
跳转表更容易,因为您希望每次调用都有类似的输出。因此,您可能会这样做......FAULT
#define FAULT_TABLE(FAULT) \
FAULT(INVALID, FAULT_CATEGORY_NONE, action_none) \
FAULT(COMMS_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(QUEUE_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(SENSOR_FAILURE, FAULT_CATEGORY_1, action_1) \
FAULT(FAILED_OP, FAULT_CATEGORY_1, action_1)
#define ENUM_CONST(fault, cat, action) fault,
#define ACTION_ENTRY(fault, cat, action) [fault] = action,
enum fault {
FAULT_TABLE(ENUM_CONST)
DUMMY_FAULT
};
const void (*fault_action[])(void) = {
FAULT_TABLE(ACTION_ENTRY)
0
};
但同样,我认为与直接编写枚举和跳转表相比,没有太大优势。
评论
void (* const fault_action[])(void)
typedef void fault_action_t (void);
const fault_action_t* fault_action[] = ...
fault_action
FAULT_TABLE
fault_action
NUM_FAULTS
上一个:X-宏列表与自身的笛卡尔积
下一个:C - X 宏自迭代/扩展
评论
typedef enum { FAULT_CATEGORY_NONE, FAULT_CATEGORY_1, FAULT_CATEGORY_N, } my_type;