是否可以定义扩展为“BUILD(a, i)
”的C / C ++宏“x[0], x[1], x[2], ..., x[i]
”?喜欢
#define BUILD(x, 0) x[0]
#define BUILD(x, 1) x[0], x[1]
#define BUILD(x, 2) x[0], x[1], x[2]
...
似乎BOOST_PP_ENUM_PARAMS可以完成这项工作。我想我可以#include boost,但我有兴趣知道它是如何以及为什么有效,任何人都可以解释?
我想调用一个函数f(int, ...)
,它接受N个参数x[i]
,0< = i< N.已知N为ceil(sizeof(A) / sizeof(B))
。所以不幸的是,我无法使用varargs或模板。
答案 0 :(得分:14)
这是可能的,但你必须做一些手工工作并有一个上限。
#define BUILD0(x) x[0]
#define BUILD1(x) BUILD0(x), x[1]
#define BUILD2(x) BUILD1(x), x[2]
#define BUILD3(x) BUILD2(x), x[3]
#define BUILD(x, i) BUILD##i(x)
请注意i
应该是整数文字,而不是常量计算值。
编辑:boost预处理器库使用类似的技术。通过额外的技巧来解决一些极端情况问题,在更高级别的设施之间共享实现宏,解决编译器错误等...通常的增强复杂性,这在通用库的上下文中是正常的,但有时会妨碍对实施原则。可能最引人注目的技巧是添加间接级别,这样如果第二个参数可以是宏,它就会被扩展。即与
#define BUILD_(x, i) BUILD##i(x)
#define BUILD(x, i) BUILD_(x, i)
可以拨打电话
#define FOO 42
BUILD(x, FOO)
这与我曝光的内容无法实现。
答案 1 :(得分:2)
不,它不是 - 宏不能递归。你发布的宏 不是可变参数,这意味着“具有不同数量的参数”。
答案 2 :(得分:0)
确定, 我遇到了同样的问题,我的目标是使用宏打印N个字节数组的所有值。我假设你有几乎相同的问题。如果是这种情况,这个解决方案应该适合未来类似的问题。
#define HEX_ARRAY_AS_STR(array, len) \
({ \
int print_counter = 0; \
print_buf = calloc(len*3+1, 1); \
char *tmp_print_buf = print_buf; \
uint8_t *array_flower = array; \
while(print_counter++ < (len)){ \
sprintf(tmp_print_buf, "%02X ", *(array_flower)++); \
tmp_print_buf += 3; \
} \
print_buf; \
})
#define eprintf(...) \
do{ \
char *print_buf; \
printf(__VA_ARGS__); \
if(print_buf) \
free(print_buf); \
}while(0)
int
main(int argc, char *argv[])
{
uint8_t sample[] = {0,1,2,3,4,5,6,7};
eprintf("%s\n", HEX_ARRAY_AS_STR(sample, 8));
return 0;
}