我正在使用C语言中的两个宏,并希望将它们组合在一起以初始化字符串array.以下是有问题的宏:

#define FOREACH_T(ACTION) \
ACTION("T1", 1) \
ACTION("T2", 2) \
ACTION("T3", 3) 

#define FOREACH_K(ACTION) \
ACTION("K1", 17) \
ACTION("K2", 20) \
ACTION("K3", 23) 

我的目标是以某种方式组合这些宏,以获得一个值数组,例如,索引[1 + 17]处的元素是"T1_K1".

对于如何组合这些宏以达到所需的结果,我有点困惑.我想要这样的东西:

const char* value[] = { [1 + 17] = "T1_K1", [1 + 20] = "T1_K2", [1 + 23] = "T1_K3",
                        [2 + 17] = "T2_K1", [2 + 20] = "T2_K2", [2 + 23] = "T2_K3",
                        [3 + 17] = "T3_K1", [3 + 20] = "T3_K2", [3 + 23] = "T3_K3"};
};

推荐答案

如果您可以更改列表宏,那么就很简单了.在不更改宏的情况下这样做也应该是可能的,但难度更大.

#define FOREACH_T(ACTION, ...) \
    ACTION("T1", 1, __VA_ARGS__) \
    ACTION("T2", 2, __VA_ARGS__) \
    ACTION("T3", 3, __VA_ARGS__) 

#define FOREACH_K(ACTION, ...) \
    ACTION("K1", 17, __VA_ARGS__) \
    ACTION("K2", 18, __VA_ARGS__) \
    ACTION("K3", 19, __VA_ARGS__) 

#define FOO(s, x, s2, x2) [x + x2] = s "_" s2,
#define FOO2(s, x, ...) FOREACH_T(FOO, s, x)

const char* value[] = {
    FOREACH_K(FOO2,)
};

请注意,这会发出warning: initializer overrides prior initialization of this subobject,因为例如1+18 == 2+17等等.


在不更改宏的情况下,也是一样的.它使用macro_sequence_for,这是我为编写预处理器循环而创建的一个库,否则这些循环会太复杂.

请注意,使用这种方法,您可能会将宏简化为类似于("T1",1)("T2",2)("T3",3)的列表,而不需要接受另一个宏作为参数.此解决方案最终首先将列表转换为此表单.

run on gcc.godbolt.org

#include <macro_sequence_for.h>

#define FOREACH_T(ACTION) \
    ACTION("T1", 1) \
    ACTION("T2", 2) \
    ACTION("T3", 3)

#define FOREACH_K(ACTION) \
    ACTION("K1", 17) \
    ACTION("K2", 18) \
    ACTION("K3", 19)

#define IDENTITY(...) __VA_ARGS__
#define PARENS(...) (__VA_ARGS__)

#define BODY(n, d, name, value) BODY2(IDENTITY d, name, value)
#define BODY2(...) BODY3(__VA_ARGS__)
#define BODY3(name1, value1, name2, value2) [value1 + value2] = name1 "_" name2,

#define OUTER_BODY(n, d, name, value) SF_FOR_EACH0(BODY, SF_STATE, SF_NULL, (name, value), FOREACH_K(PARENS))

const char *value[] = {
    SF_FOR_EACH(OUTER_BODY, SF_NULL, SF_NULL,, FOREACH_T(PARENS))
};

C++相关问答推荐

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

位屏蔽对于无符号转换是强制的吗?

使用SWI—Prolog的qsave_program生成二进制文件有什么好处?'

以c格式打印时间戳

如何跨平台处理UTF-16字符串?

在编译时参数化类型定义

struct 上的OpenMP缩减

LONG_DOUBLE_T是否存在(标准C:C23)

RawMotion的XInput2错误(具有较高值的XISelectEvents上的BadValue)

如何在提取的索引中分配空值?

Tic-tac-toe:从文件加载存储

使用%f格式说明符打印整数值

如何修复我的qsort()算法?它每次都给出不同的结果

try 查找带有指针的数组的最小值和最大值

为什么我的旧式&q;函数在传递浮点数时会打印2?

从整型转换为浮点型可能会改变其值.

当我在34mb的.mp4文件中使用FREAD时,我得到了一个分段错误,我如何解决它?

DennisM.Ritchie的C编程语言一书中关于二进制搜索的代码出现错误?

如何为avr atmega32微控制器构建C代码,通过光电二极管捕获光强度并通过串行通信传输数据

在 C 中传递参数时出现整数溢出