【发布时间】:2022-07-17 00:19:28
【问题描述】:
假设我有带有签名的函数bshow()
void bshow(int arg0, int arg1, int arg2);
但出于任意原因,我想将其实现为宏。
此外,我希望函数具有默认参数
int arg0=0x10;
int arg1=0x11;
int arg2=0x12;
我已经为bshow() 是一个函数的情况做了这个,使用standard tricks。
但是我怎么能把它作为一个宏呢?
例如。假设我有一个宏 nargs(),它使用 C 预处理器来计算参数的数量。例如。
nargs() // get replaced by 0 by the preprocessor
nargs(a) // get replaced by 1 by the preprocessor
nargs(a,b) // get replaced by 2 by the preprocessor
我想做一些类似的事情(这是行不通的):
#define arg0_get(a0,...) a0
#define arg1_get(a0,a1,...) a1
#define arg2_get(a0,a1,a2,...) a2
#define bshow(...) do{ \
int arg0=0x10; if(0<nargs(__VA_ARGS__)) arg0 = arg0_get(__VA_ARGS__); \
int arg1=0x11; if(1<nargs(__VA_ARGS__)) arg1 = arg1_get(__VA_ARGS__); \
int arg2=0x12; if(2<nargs(__VA_ARGS__)) arg2 = arg2_get(__VA_ARGS__); \
/* do stuff here */ \
}while(0)
其实我已经将bshow()函数实现为宏,如下(这里有实际参数个数):
#define __bshow(bdim,data, nbits,ncols,base)({ \
bdim,data, nbits,ncols,base; \
putchar(0x0a); \
printf("nbits %d\n",nbits); \
printf("ncols %d\n",ncols); \
printf("base %d\n",base); \
})
#define _bshow(bdim,data, nbits,ncols,base, ...) __bshow(bdim,data, nbits,ncols,base)
#define bshow(...) \
if( 2==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 32,24,16,0,__VA_ARGS__); \
else if(3==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 24,16,0,__VA_ARGS__); \
else if(4==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 16,0,__VA_ARGS__); \
else if(5==nargs(__VA_ARGS__)) _bshow(__VA_ARGS__, 0,__VA_ARGS__); \
// test
bshow(0,1);
bshow(0,1, 10);
bshow(0,1, 10,11);
bshow(0,1, 10,11,12);
编辑:
建议的解决方案没有达到预期的效果,因为它似乎“实例化”宏的所有实例,这通常会产生意想不到的后果。
但我想知道是否有更优雅的方式来做到这一点。
在它自己的宏中抽象出整个结构也很好,这样人们就可以轻松地将它应用到其他函数中,而不是必须为每个函数/宏手动编写样板。
this 也没有太大帮助。
【问题讨论】:
-
这不可能以任何优雅的方式实现的原因是因为原始规范没有意义 - 你不应该想要有可变数量的参数到一个函数,因为它本身并不能解决任何实际的现实问题。只需创建一个接受数组和大小的函数。
-
我真的很困惑,你问了一个问题,然后用一年前的视频回答了这个问题?您需要任何额外的帮助吗?因为我不确定您的编辑是否与您的答案有关。
标签: c macros c-preprocessor default-value variadic-macros