有没有一种方法可以编写一个C预处理器宏,根据其接收到的参数而展开为不同的内容?
#define foo() ???
/* 1 */
foo(name)
/* 2 */
foo(_)
期望的结果:
/* 1 */
int name;
/* 2 */
/*ignore*/
是的,我知道宏很邪恶。我问这个问题主要是出于好奇。
补充Gavin Smith的答案,实际上您可以在宏展开中检查条件:
#define FOO_name 1
#define FOO__ 0
#define CONC(a,b) a##_##b
#define IF(c, t, e) CONC(IF, c)(t, e)
#define IF_0(t, e) e
#define IF_1(t, e) t
#define FOO(x) IF(CONC(FOO,x), int x;, )
FOO(name) // -> int name;
FOO(_) // -> /*nothing*/
#define FOO_NAME 1
#define FOO__ 2
#define CONC(a,b) a##_##b
#define FOO(x) CONC(FOO,x)
我认为无法在C宏扩展内部检查条件。
我能想到的最好办法是使用字符串化运算符#
将宏参数转换为字符串文字,然后使用运行时函数进行检查。(但这对于您要输出变量声明的情况不起作用。)
例如,以下代码将打印“011”:
#define FOO(x) (strcmp("NAME", #x) ? 1 : 0)
main()
{
printf("%d", FOO(NAME));
printf("%d", FOO(1));
printf("%d", FOO(2));
}
strcmp
比较,因此效率不会比真正的预处理条件差。但是,将FOO
变为普通函数会更清晰,而且可能同样高效。使用这里描述的技巧,可以在编译时实现所需操作。
您可以使用文档末尾定义的EQUAL
宏,并执行以下操作:
#define COMPARE__(x) x
#define OPTION_0(x) int x;
#define OPTION_1(x) /* nothing */
#define foo(x) CAT(OPTION_, EQUAL(_, x))(x)
foo(name1) // int name1;
foo(_) // /* nothing */
foo(name2) // int name2;
foo(a,b)
、foo(a,_)
、foo(_,b)
和foo(_,_)
。 - hugomg